libnxsl, libnxdb, libnxsrv, nxget, and nxdbmgr are now UNICODE compatible; libtre...
[public/netxms.git] / src / server / core / node.cpp
CommitLineData
5039dede
AK
1/*
2** NetXMS - Network Management System
7c521895 3** Copyright (C) 2003-2010 Victor Kirhenshtein
5039dede
AK
4**
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.
9**
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.
14**
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.
18**
19** File: node.cpp
20**
21**/
22
23#include "nxcore.h"
24
25
26//
5039dede
AK
27// Node class default constructor
28//
29
30Node::Node()
31 :Template()
32{
a65c1819 33 m_iStatus = STATUS_UNKNOWN;
5039dede
AK
34 m_dwFlags = 0;
35 m_dwDynamicFlags = 0;
36 m_dwZoneGUID = 0;
37 m_dwNodeType = NODE_TYPE_GENERIC;
38 m_wAgentPort = AGENT_LISTEN_PORT;
39 m_wAuthMethod = AUTH_NONE;
40 m_szSharedSecret[0] = 0;
41 m_iStatusPollType = POLL_ICMP_PING;
5d2c5741 42 m_snmpVersion = SNMP_VERSION_1;
5039dede 43 m_wSNMPPort = SNMP_DEFAULT_PORT;
5d2c5741
VK
44 TCHAR community[MAX_COMMUNITY_LENGTH];
45 ConfigReadStr("DefaultCommunityString", community,
5039dede 46 MAX_COMMUNITY_LENGTH, "public");
5d2c5741 47 m_snmpSecurity = new SNMP_SecurityContext(community);
5039dede
AK
48 m_szObjectId[0] = 0;
49 m_tLastDiscoveryPoll = 0;
50 m_tLastStatusPoll = 0;
51 m_tLastConfigurationPoll = 0;
52 m_tLastRTUpdate = 0;
53 m_hPollerMutex = MutexCreate();
54 m_hAgentAccessMutex = MutexCreate();
55 m_mutexRTAccess = MutexCreate();
56 m_mutexTopoAccess = MutexCreate();
57 m_pAgentConnection = NULL;
58 m_szAgentVersion[0] = 0;
59 m_szPlatformName[0] = 0;
60 m_szSysDescription[0] = 0;
61 m_dwNumParams = 0;
62 m_pParamList = NULL;
63 m_dwPollerNode = 0;
64 m_dwProxyNode = 0;
65 m_dwSNMPProxy = 0;
66 memset(m_qwLastEvents, 0, sizeof(QWORD) * MAX_LAST_EVENTS);
67 m_pRoutingTable = NULL;
68 m_tFailTimeSNMP = 0;
69 m_tFailTimeAgent = 0;
70 m_pTopology = NULL;
71 m_tLastTopologyPoll = 0;
72 m_iPendingStatus = -1;
73 m_iPollCount = 0;
74 m_iRequiredPollCount = 0; // Use system default
75 m_nUseIfXTable = IFXTABLE_DEFAULT; // Use system default
ab621f39 76 m_jobQueue = new ServerJobQueue();
5039dede
AK
77}
78
79
80//
81// Constructor for new node object
82//
83
84Node::Node(DWORD dwAddr, DWORD dwFlags, DWORD dwProxyNode, DWORD dwSNMPProxy, DWORD dwZone)
85 :Template()
86{
a65c1819 87 m_iStatus = STATUS_UNKNOWN;
5039dede
AK
88 m_dwIpAddr = dwAddr;
89 m_dwFlags = dwFlags;
90 m_dwDynamicFlags = 0;
91 m_dwZoneGUID = dwZone;
92 m_dwNodeType = NODE_TYPE_GENERIC;
93 m_wAgentPort = AGENT_LISTEN_PORT;
94 m_wAuthMethod = AUTH_NONE;
95 m_szSharedSecret[0] = 0;
96 m_iStatusPollType = POLL_ICMP_PING;
5d2c5741 97 m_snmpVersion = SNMP_VERSION_1;
5039dede 98 m_wSNMPPort = SNMP_DEFAULT_PORT;
5d2c5741
VK
99 TCHAR community[MAX_COMMUNITY_LENGTH];
100 ConfigReadStr("DefaultCommunityString", community,
5039dede 101 MAX_COMMUNITY_LENGTH, "public");
5d2c5741 102 m_snmpSecurity = new SNMP_SecurityContext(community);
5039dede
AK
103 IpToStr(dwAddr, m_szName); // Make default name from IP address
104 m_szObjectId[0] = 0;
105 m_tLastDiscoveryPoll = 0;
106 m_tLastStatusPoll = 0;
107 m_tLastConfigurationPoll = 0;
108 m_tLastRTUpdate = 0;
109 m_hPollerMutex = MutexCreate();
110 m_hAgentAccessMutex = MutexCreate();
111 m_mutexRTAccess = MutexCreate();
112 m_mutexTopoAccess = MutexCreate();
113 m_pAgentConnection = NULL;
114 m_szAgentVersion[0] = 0;
115 m_szPlatformName[0] = 0;
116 m_szSysDescription[0] = 0;
117 m_dwNumParams = 0;
118 m_pParamList = NULL;
119 m_dwPollerNode = 0;
120 m_dwProxyNode = dwProxyNode;
121 m_dwSNMPProxy = dwSNMPProxy;
122 memset(m_qwLastEvents, 0, sizeof(QWORD) * MAX_LAST_EVENTS);
123 m_bIsHidden = TRUE;
124 m_pRoutingTable = NULL;
125 m_tFailTimeSNMP = 0;
126 m_tFailTimeAgent = 0;
127 m_pTopology = NULL;
128 m_tLastTopologyPoll = 0;
129 m_iPendingStatus = -1;
130 m_iPollCount = 0;
131 m_iRequiredPollCount = 0; // Use system default
132 m_nUseIfXTable = IFXTABLE_DEFAULT; // Use system default
ab621f39 133 m_jobQueue = new ServerJobQueue();
5039dede
AK
134}
135
136
137//
138// Node destructor
139//
140
141Node::~Node()
142{
143 MutexDestroy(m_hPollerMutex);
144 MutexDestroy(m_hAgentAccessMutex);
145 MutexDestroy(m_mutexRTAccess);
146 MutexDestroy(m_mutexTopoAccess);
147 delete m_pAgentConnection;
148 safe_free(m_pParamList);
149 DestroyRoutingTable(m_pRoutingTable);
150 delete m_pTopology;
ab621f39 151 delete m_jobQueue;
5d2c5741 152 delete m_snmpSecurity;
5039dede
AK
153}
154
155
156//
157// Create object from database data
158//
159
160BOOL Node::CreateFromDB(DWORD dwId)
161{
5d2c5741 162 TCHAR query[1024];
5039dede
AK
163 DB_RESULT hResult;
164 int i, iNumRows;
165 DWORD dwSubnetId;
166 NetObj *pObject;
167 BOOL bResult = FALSE;
168
169 m_dwId = dwId;
170
171 if (!LoadCommonProperties())
172 {
173 DbgPrintf(2, "Cannot load common properties for node object %d", dwId);
174 return FALSE;
175 }
176
5d2c5741
VK
177 _sntprintf(query, 1024, _T("SELECT primary_ip,node_flags,")
178 _T("snmp_version,auth_method,secret,")
179 _T("agent_port,status_poll_type,snmp_oid,")
180 _T("node_type,agent_version,")
181 _T("platform_name,poller_node_id,zone_guid,")
182 _T("proxy_node,snmp_proxy,required_polls,uname,")
65e2005b 183 _T("use_ifxtable,snmp_port,community,usm_auth_password,")
5d2c5741
VK
184 _T("usm_priv_password,usm_methods")
185 _T(" FROM nodes WHERE id=%d"), dwId);
186 hResult = DBSelect(g_hCoreDB, query);
e2babedf 187 if (hResult == NULL)
5039dede
AK
188 return FALSE; // Query failed
189
190 if (DBGetNumRows(hResult) == 0)
191 {
192 DBFreeResult(hResult);
5d2c5741 193 DbgPrintf(2, _T("Missing record in \"nodes\" table for node object %d"), dwId);
5039dede
AK
194 return FALSE;
195 }
196
197 m_dwIpAddr = DBGetFieldIPAddr(hResult, 0, 0);
198 m_dwFlags = DBGetFieldULong(hResult, 0, 1);
5d2c5741 199 m_snmpVersion = DBGetFieldLong(hResult, 0, 2);
5039dede
AK
200 m_wAuthMethod = (WORD)DBGetFieldLong(hResult, 0, 3);
201 DBGetField(hResult, 0, 4, m_szSharedSecret, MAX_SECRET_LENGTH);
5039dede
AK
202 m_wAgentPort = (WORD)DBGetFieldLong(hResult, 0, 5);
203 m_iStatusPollType = DBGetFieldLong(hResult, 0, 6);
5d2c5741 204 DBGetField(hResult, 0, 7, m_szObjectId, MAX_OID_LEN * 4);
5d2c5741
VK
205 m_dwNodeType = DBGetFieldULong(hResult, 0, 8);
206 DBGetField(hResult, 0, 9, m_szAgentVersion, MAX_AGENT_VERSION_LEN);
5d2c5741 207 DBGetField(hResult, 0, 10, m_szPlatformName, MAX_PLATFORM_NAME_LEN);
5d2c5741
VK
208 m_dwPollerNode = DBGetFieldULong(hResult, 0, 11);
209 m_dwZoneGUID = DBGetFieldULong(hResult, 0, 12);
210 m_dwProxyNode = DBGetFieldULong(hResult, 0, 13);
211 m_dwSNMPProxy = DBGetFieldULong(hResult, 0, 14);
212 m_iRequiredPollCount = DBGetFieldLong(hResult, 0, 15);
213 DBGetField(hResult, 0, 16, m_szSysDescription, MAX_DB_STRING);
214 m_nUseIfXTable = (BYTE)DBGetFieldLong(hResult, 0, 17);
65e2005b 215 m_wSNMPPort = (WORD)DBGetFieldLong(hResult, 0, 18);
5039dede 216
5d2c5741
VK
217 // SNMP authentication parameters
218 TCHAR snmpAuthObject[256], snmpAuthPassword[256], snmpPrivPassword[256];
65e2005b
VK
219 DBGetField(hResult, 0, 19, snmpAuthObject, 256);
220 DBGetField(hResult, 0, 20, snmpAuthPassword, 256);
221 DBGetField(hResult, 0, 21, snmpPrivPassword, 256);
5d2c5741
VK
222 int snmpMethods = DBGetFieldLong(hResult, 0, 21);
223 delete m_snmpSecurity;
224 m_snmpSecurity = new SNMP_SecurityContext(snmpAuthObject, snmpAuthPassword, snmpPrivPassword, snmpMethods & 0xFF, snmpMethods >> 8);
14b98b3a 225 m_snmpSecurity->setSecurityModel((m_snmpVersion == SNMP_VERSION_3) ? SNMP_SECURITY_MODEL_USM : SNMP_SECURITY_MODEL_V2C);
5d2c5741 226
5039dede
AK
227 DBFreeResult(hResult);
228
229 if (!m_bIsDeleted)
230 {
231 // Link node to subnets
5d2c5741
VK
232 _sntprintf(query, 1024, _T("SELECT subnet_id FROM nsmap WHERE node_id=%d"), dwId);
233 hResult = DBSelect(g_hCoreDB, query);
5039dede
AK
234 if (hResult == NULL)
235 return FALSE; // Query failed
236
237 iNumRows = DBGetNumRows(hResult);
5039dede
AK
238 for(i = 0; i < iNumRows; i++)
239 {
240 dwSubnetId = DBGetFieldULong(hResult, i, 0);
241 pObject = FindObjectById(dwSubnetId);
242 if (pObject == NULL)
243 {
244 nxlog_write(MSG_INVALID_SUBNET_ID, EVENTLOG_ERROR_TYPE, "dd", dwId, dwSubnetId);
245 break;
246 }
247 else if (pObject->Type() != OBJECT_SUBNET)
248 {
249 nxlog_write(MSG_SUBNET_NOT_SUBNET, EVENTLOG_ERROR_TYPE, "dd", dwId, dwSubnetId);
250 break;
251 }
252 else
253 {
254 pObject->AddChild(this);
255 AddParent(pObject);
5039dede
AK
256 }
257 }
258
259 DBFreeResult(hResult);
7c521895 260 loadItemsFromDB();
5039dede
AK
261 LoadACLFromDB();
262
263 // Walk through all items in the node and load appropriate thresholds
a6c1f07f 264 bResult = TRUE;
5039dede 265 for(i = 0; i < (int)m_dwNumItems; i++)
fb05c05b 266 if (!m_ppItems[i]->loadThresholdsFromDB())
5039dede 267 {
5d2c5741 268 DbgPrintf(3, _T("Cannot load thresholds for DCI %d of node %d (%s)"),
fb05c05b 269 m_ppItems[i]->getId(), dwId, m_szName);
5039dede
AK
270 bResult = FALSE;
271 }
272 }
273 else
274 {
275 bResult = TRUE;
276 }
277
278 return bResult;
279}
280
281
282//
283// Save object to database
284//
285
286BOOL Node::SaveToDB(DB_HANDLE hdb)
287{
65e2005b 288 TCHAR szQuery[4096], szIpAddr[16];
5039dede
AK
289 DB_RESULT hResult;
290 BOOL bNewObject = TRUE;
291 BOOL bResult;
292
293 // Lock object's access
294 LockData();
295
296 SaveCommonProperties(hdb);
297
298 // Check for object's existence in database
65e2005b 299 _sntprintf(szQuery, 4096, _T("SELECT id FROM nodes WHERE id=%d"), m_dwId);
5039dede
AK
300 hResult = DBSelect(hdb, szQuery);
301 if (hResult != 0)
302 {
303 if (DBGetNumRows(hResult) > 0)
304 bNewObject = FALSE;
305 DBFreeResult(hResult);
306 }
307
308 // Form and execute INSERT or UPDATE query
4b7d8903 309 int snmpMethods = m_snmpSecurity->getAuthMethod() | (m_snmpSecurity->getPrivMethod() << 8);
5039dede 310 if (bNewObject)
65e2005b
VK
311 {
312 _sntprintf(szQuery, 4096,
313 _T("INSERT INTO nodes (id,primary_ip,snmp_port,")
314 _T("node_flags,snmp_version,community,status_poll_type,")
315 _T("agent_port,auth_method,secret,snmp_oid,proxy_node,")
316 _T("node_type,agent_version,platform_name,uname,")
317 _T("poller_node_id,zone_guid,snmp_proxy,required_polls,")
318 _T("use_ifxtable,usm_auth_password,usm_priv_password,usm_methods) VALUES ")
e642792a 319 _T("(%d,'%s',%d,%d,%d,%s,%d,%d,%d,%s,%s,%d,%d,%s,%s,%s,%d,%d,%d,%d,%d,%s,%s,%d)"),
65e2005b
VK
320 m_dwId, IpToStr(m_dwIpAddr, szIpAddr), (int)m_wSNMPPort, m_dwFlags,
321 m_snmpVersion, (const TCHAR *)DBPrepareString(hdb, m_snmpSecurity->getCommunity()),
322 m_iStatusPollType, (int)m_wAgentPort, m_wAuthMethod,
323 (const TCHAR *)DBPrepareString(hdb, m_szSharedSecret),
324 (const TCHAR *)DBPrepareString(hdb, m_szObjectId),
325 m_dwProxyNode, m_dwNodeType, (const TCHAR *)DBPrepareString(hdb, m_szAgentVersion),
326 (const TCHAR *)DBPrepareString(hdb, m_szPlatformName),
327 (const TCHAR *)DBPrepareString(hdb, m_szSysDescription),
328 m_dwPollerNode, m_dwZoneGUID, m_dwSNMPProxy, m_iRequiredPollCount, m_nUseIfXTable,
329 (const TCHAR *)DBPrepareString(hdb, m_snmpSecurity->getAuthPassword()),
330 (const TCHAR *)DBPrepareString(hdb, m_snmpSecurity->getPrivPassword()), snmpMethods);
331 }
5039dede 332 else
65e2005b
VK
333 {
334 _sntprintf(szQuery, 4096,
335 _T("UPDATE nodes SET primary_ip='%s',snmp_port=%d,")
336 _T("node_flags=%d,snmp_version=%d,community=%s,")
337 _T("status_poll_type=%d,agent_port=%d,auth_method=%d,secret=%s,")
338 _T("snmp_oid=%s,node_type=%d,uname=%s,")
339 _T("agent_version=%s,platform_name=%s,poller_node_id=%d,")
340 _T("zone_guid=%d,proxy_node=%d,snmp_proxy=%d,")
341 _T("required_polls=%d,use_ifxtable=%d,usm_auth_password=%s,")
342 _T("usm_priv_password=%s,usm_methods=%d WHERE id=%d"),
343 IpToStr(m_dwIpAddr, szIpAddr), m_wSNMPPort,
344 m_dwFlags, m_snmpVersion, (const TCHAR *)DBPrepareString(hdb, m_snmpSecurity->getCommunity()),
345 m_iStatusPollType, m_wAgentPort, m_wAuthMethod,
346 (const TCHAR *)DBPrepareString(hdb, m_szSharedSecret),
347 (const TCHAR *)DBPrepareString(hdb, m_szObjectId), m_dwNodeType,
348 (const TCHAR *)DBPrepareString(hdb, m_szSysDescription),
349 (const TCHAR *)DBPrepareString(hdb, m_szAgentVersion),
350 (const TCHAR *)DBPrepareString(hdb, m_szPlatformName), m_dwPollerNode, m_dwZoneGUID,
351 m_dwProxyNode, m_dwSNMPProxy, m_iRequiredPollCount,
352 m_nUseIfXTable, (const TCHAR *)DBPrepareString(hdb, m_snmpSecurity->getAuthPassword()),
353 (const TCHAR *)DBPrepareString(hdb, m_snmpSecurity->getPrivPassword()), snmpMethods, m_dwId);
354 }
5039dede 355 bResult = DBQuery(hdb, szQuery);
5039dede 356
7c521895
VK
357 // Save access list
358 SaveACLToDB(hdb);
359
360 UnlockData();
361
5039dede
AK
362 // Save data collection items
363 if (bResult)
364 {
365 DWORD i;
366
7c521895 367 lockDciAccess();
5039dede 368 for(i = 0; i < m_dwNumItems; i++)
fb05c05b 369 m_ppItems[i]->saveToDB(hdb);
7c521895 370 unlockDciAccess();
5039dede
AK
371 }
372
7c521895
VK
373 // Clear modifications flag
374 LockData();
5039dede 375 m_bIsModified = FALSE;
7c521895 376 UnlockData();
5039dede 377
7c521895 378 return bResult;
5039dede
AK
379}
380
381
382//
383// Delete object from database
384//
385
65e2005b 386BOOL Node::DeleteFromDB()
5039dede
AK
387{
388 char szQuery[256];
389 BOOL bSuccess;
390
391 bSuccess = Template::DeleteFromDB();
392 if (bSuccess)
393 {
65e2005b 394 _sntprintf(szQuery, 256, _T("DELETE FROM nodes WHERE id=%d"), m_dwId);
5039dede 395 QueueSQLRequest(szQuery);
65e2005b 396 _sntprintf(szQuery, 256, _T("DELETE FROM nsmap WHERE node_id=%d"), m_dwId);
5039dede 397 QueueSQLRequest(szQuery);
65e2005b 398 _sntprintf(szQuery, 256, _T("DROP TABLE idata_%d"), m_dwId);
5039dede
AK
399 QueueSQLRequest(szQuery);
400 }
401 return bSuccess;
402}
403
404
405//
406// Get ARP cache from node
407//
408
7c521895 409ARP_CACHE *Node::getArpCache()
5039dede
AK
410{
411 ARP_CACHE *pArpCache = NULL;
412
413 if (m_dwFlags & NF_IS_LOCAL_MGMT)
414 {
415 pArpCache = GetLocalArpCache();
416 }
417 else if (m_dwFlags & NF_IS_NATIVE_AGENT)
418 {
7c521895
VK
419 agentLock();
420 if (connectToAgent())
5039dede 421 pArpCache = m_pAgentConnection->GetArpCache();
7c521895 422 agentUnlock();
5039dede
AK
423 }
424 else if (m_dwFlags & NF_IS_SNMP)
425 {
426 SNMP_Transport *pTransport;
427
cd9f247e 428 pTransport = createSnmpTransport();
803d47be
VK
429 if (pTransport != NULL)
430 {
431 pArpCache = SnmpGetArpCache(m_snmpVersion, pTransport);
432 delete pTransport;
433 }
5039dede
AK
434 }
435
436 return pArpCache;
437}
438
439
440//
441// Get list of interfaces from node
442//
443
58b3e451 444INTERFACE_LIST *Node::getInterfaceList()
5039dede
AK
445{
446 INTERFACE_LIST *pIfList = NULL;
447
b741f151 448 if ((m_dwFlags & NF_IS_NATIVE_AGENT) && (!(m_dwFlags & NF_DISABLE_NXCP)))
5039dede 449 {
7c521895
VK
450 agentLock();
451 if (connectToAgent())
5039dede
AK
452 {
453 pIfList = m_pAgentConnection->GetInterfaceList();
454 CleanInterfaceList(pIfList);
455 }
7c521895 456 agentUnlock();
5039dede 457 }
b741f151
VK
458 if ((pIfList == NULL) && (m_dwFlags & NF_IS_LOCAL_MGMT))
459 {
460 pIfList = GetLocalInterfaceList();
461 }
5039dede
AK
462 if ((pIfList == NULL) && (m_dwFlags & NF_IS_SNMP) &&
463 (!(m_dwFlags & NF_DISABLE_SNMP)))
464 {
465 SNMP_Transport *pTransport;
466 BOOL useIfXTable;
467
cd9f247e 468 pTransport = createSnmpTransport();
803d47be 469 if (pTransport != NULL)
5039dede 470 {
803d47be
VK
471 if (m_nUseIfXTable == IFXTABLE_DEFAULT)
472 {
473 useIfXTable = (ConfigReadInt(_T("UseIfXTable"), 1) != 0);
474 }
475 else
476 {
477 useIfXTable = (m_nUseIfXTable == IFXTABLE_ENABLED);
478 }
479 pIfList = SnmpGetInterfaceList(m_snmpVersion, pTransport, m_dwNodeType, useIfXTable);
480 delete pTransport;
5039dede 481 }
5039dede
AK
482 }
483
484 if (pIfList != NULL)
485 CheckInterfaceNames(pIfList);
486
487 return pIfList;
488}
489
490
491//
492// Find interface by index and node IP
493// Returns pointer to interface object or NULL if appropriate interface couldn't be found
494//
495
58b3e451 496Interface *Node::findInterface(DWORD dwIndex, DWORD dwHostAddr)
5039dede
AK
497{
498 DWORD i;
499 Interface *pInterface;
500
501 LockChildList(FALSE);
502 for(i = 0; i < m_dwChildCount; i++)
503 if (m_pChildList[i]->Type() == OBJECT_INTERFACE)
504 {
505 pInterface = (Interface *)m_pChildList[i];
506 if (pInterface->IfIndex() == dwIndex)
507 {
508 if (((pInterface->IpAddr() & pInterface->IpNetMask()) ==
509 (dwHostAddr & pInterface->IpNetMask())) ||
510 (dwHostAddr == INADDR_ANY))
511 {
512 UnlockChildList();
513 return pInterface;
514 }
515 }
516 }
517 UnlockChildList();
518 return NULL;
519}
520
521
522//
523// Check if given IP address is one of node's interfaces
524//
525
58b3e451 526BOOL Node::isMyIP(DWORD dwIpAddr)
5039dede
AK
527{
528 DWORD i;
529
530 LockChildList(FALSE);
531 for(i = 0; i < m_dwChildCount; i++)
532 if (m_pChildList[i]->Type() == OBJECT_INTERFACE)
533 {
534 if (((Interface *)m_pChildList[i])->IpAddr() == dwIpAddr)
535 {
536 UnlockChildList();
537 return TRUE;
538 }
539 }
540 UnlockChildList();
541 return FALSE;
542}
543
544
545//
546// Create new interface
547//
548
549void Node::CreateNewInterface(DWORD dwIpAddr, DWORD dwNetMask, char *szName,
550 DWORD dwIndex, DWORD dwType, BYTE *pbMacAddr)
551{
552 Interface *pInterface;
553 Subnet *pSubnet = NULL;
554 Cluster *pCluster;
555 BOOL bAddToSubnet, bSyntheticMask = FALSE;
556
557 DbgPrintf(5, _T("Node::CreateNewInterface(%08X, %08X, %s, %d, %d) called for node %s [%d]"),
558 dwIpAddr, dwNetMask, szName, dwIndex, dwType, m_szName, m_dwId);
559
560 // Find subnet to place interface object to
561 if (dwIpAddr != 0)
562 {
7c521895 563 pCluster = getMyCluster();
58b3e451 564 bAddToSubnet = (pCluster != NULL) ? !pCluster->isSyncAddr(dwIpAddr) : TRUE;
5039dede
AK
565 DbgPrintf(5, _T("Node::CreateNewInterface: node=%s [%d] cluster=%s [%d] add=%d"),
566 m_szName, m_dwId, (pCluster != NULL) ? pCluster->Name() : _T("(null)"),
567 (pCluster != NULL) ? pCluster->Id() : 0, bAddToSubnet);
568 if (bAddToSubnet)
569 {
570 pSubnet = FindSubnetForNode(dwIpAddr);
571 if (pSubnet == NULL)
572 {
573 // Check if netmask is 0 (detect), and if yes, create
574 // new subnet with class mask
575 if (dwNetMask == 0)
576 {
577 bSyntheticMask = TRUE;
578 if (dwIpAddr < 0xE0000000)
579 {
580 dwNetMask = 0xFFFFFF00; // Class A, B or C
581 }
582 else
583 {
584 TCHAR szBuffer[16];
585
586 // Multicast address??
587 DbgPrintf(2, _T("Attempt to create interface object with multicast address %s"),
588 IpToStr(dwIpAddr, szBuffer));
589 }
590 }
591
592 // Create new subnet object
593 if (dwIpAddr < 0xE0000000)
594 {
595 pSubnet = new Subnet(dwIpAddr & dwNetMask, dwNetMask, m_dwZoneGUID, bSyntheticMask);
596 NetObjInsert(pSubnet, TRUE);
597 g_pEntireNet->AddSubnet(pSubnet);
598 }
599 }
600 else
601 {
602 // Set correct netmask if we was asked for it
603 if (dwNetMask == 0)
604 {
605 dwNetMask = pSubnet->IpNetMask();
606 bSyntheticMask = pSubnet->IsSyntheticMask();
607 }
608 }
609 }
610 }
611
612 // Create interface object
613 if (szName != NULL)
614 pInterface = new Interface(szName, dwIndex, dwIpAddr, dwNetMask, dwType);
615 else
616 pInterface = new Interface(dwIpAddr, dwNetMask, bSyntheticMask);
617 if (pbMacAddr != NULL)
618 pInterface->SetMacAddr(pbMacAddr);
619
620 // Insert to objects' list and generate event
621 NetObjInsert(pInterface, TRUE);
622 AddInterface(pInterface);
623 if (!m_bIsHidden)
624 pInterface->Unhide();
625 PostEvent(EVENT_INTERFACE_ADDED, m_dwId, "dsaad", pInterface->Id(),
626 pInterface->Name(), pInterface->IpAddr(),
627 pInterface->IpNetMask(), pInterface->IfIndex());
628
629 // Bind node to appropriate subnet
630 if (pSubnet != NULL)
631 {
632 pSubnet->AddNode(this);
633
634 // Check if subnet mask is correct on interface
635 if ((pSubnet->IpNetMask() != pInterface->IpNetMask()) &&
636 (!pSubnet->IsSyntheticMask()))
637 {
638 PostEvent(EVENT_INCORRECT_NETMASK, m_dwId, "idsaa", pInterface->Id(),
639 pInterface->IfIndex(), pInterface->Name(),
640 pInterface->IpNetMask(), pSubnet->IpNetMask());
641 }
642 }
643}
644
645
646//
647// Delete interface from node
648//
649
650void Node::DeleteInterface(Interface *pInterface)
651{
652 DWORD i;
653
654 // Check if we should unlink node from interface's subnet
655 if (pInterface->IpAddr() != 0)
656 {
657 BOOL bUnlink = TRUE;
658
659 LockChildList(FALSE);
660 for(i = 0; i < m_dwChildCount; i++)
661 if (m_pChildList[i]->Type() == OBJECT_INTERFACE)
662 if (m_pChildList[i] != pInterface)
663 if ((((Interface *)m_pChildList[i])->IpAddr() & ((Interface *)m_pChildList[i])->IpNetMask()) ==
664 (pInterface->IpAddr() & pInterface->IpNetMask()))
665 {
666 bUnlink = FALSE;
667 break;
668 }
669 UnlockChildList();
670
671 if (bUnlink)
672 {
673 // Last interface in subnet, should unlink node
674 Subnet *pSubnet = FindSubnetByIP(pInterface->IpAddr() & pInterface->IpNetMask());
675 if (pSubnet != NULL)
676 {
677 DeleteParent(pSubnet);
678 pSubnet->DeleteChild(this);
679 }
680 }
681 }
682 pInterface->Delete(FALSE);
683}
684
685
686//
687// Calculate node status based on child objects status
688//
689
690void Node::CalculateCompoundStatus(BOOL bForcedRecalc)
691{
692 int iOldStatus = m_iStatus;
693 static DWORD dwEventCodes[] = { EVENT_NODE_NORMAL, EVENT_NODE_MINOR,
694 EVENT_NODE_WARNING, EVENT_NODE_MAJOR, EVENT_NODE_CRITICAL,
695 EVENT_NODE_UNKNOWN, EVENT_NODE_UNMANAGED };
696
697 NetObj::CalculateCompoundStatus(bForcedRecalc);
698 if (m_iStatus != iOldStatus)
699 PostEvent(dwEventCodes[m_iStatus], m_dwId, "d", iOldStatus);
700}
701
702
703//
704// Perform status poll on node
705//
706
58b3e451 707void Node::statusPoll(ClientSession *pSession, DWORD dwRqId, int nPoller)
5039dede
AK
708{
709 DWORD i, dwPollListSize, dwOldFlags = m_dwFlags;
710 NetObj *pPollerNode = NULL, **ppPollList;
711 BOOL bAllDown;
712 Queue *pQueue; // Delayed event queue
713 SNMP_Transport *pTransport;
714 Cluster *pCluster;
715 time_t tNow, tExpire;
716
717 pQueue = new Queue;
718 SetPollerInfo(nPoller, "wait for lock");
7c521895 719 pollerLock();
5039dede
AK
720 m_pPollRequestor = pSession;
721 SendPollerMsg(dwRqId, "Starting status poll for node %s\r\n", m_szName);
722 DbgPrintf(5, "Starting status poll for node %s (ID: %d)", m_szName, m_dwId);
723
724 // Read capability expiration time and current time
725 tExpire = (time_t)ConfigReadULong(_T("CapabilityExpirationTime"), 604800);
726 tNow = time(NULL);
727
728 // Check SNMP agent connectivity
729restart_agent_check:
15d6f8c9 730 if ((m_dwFlags & NF_IS_SNMP) && (!(m_dwFlags & NF_DISABLE_SNMP)) && (m_dwIpAddr != 0))
5039dede
AK
731 {
732 TCHAR szBuffer[256];
733 DWORD dwResult;
734
735 DbgPrintf(6, "StatusPoll(%s): check SNMP", m_szName);
cd9f247e 736 pTransport = createSnmpTransport();
803d47be
VK
737 if (pTransport == NULL)
738 {
739 DbgPrintf(6, "StatusPoll(%s): cannot create SNMP transport", m_szName);
740 goto skip_snmp_check;
741 }
742
5039dede
AK
743 SetPollerInfo(nPoller, "check SNMP");
744 SendPollerMsg(dwRqId, "Checking SNMP agent connectivity\r\n");
5d2c5741
VK
745 dwResult = SnmpGet(m_snmpVersion, pTransport, ".1.3.6.1.2.1.1.2.0",
746 NULL, 0, szBuffer, 256, FALSE, FALSE);
5039dede
AK
747 if ((dwResult == SNMP_ERR_SUCCESS) || (dwResult == SNMP_ERR_NO_OBJECT))
748 {
749 if (m_dwDynamicFlags & NDF_SNMP_UNREACHABLE)
750 {
751 m_dwDynamicFlags &= ~NDF_SNMP_UNREACHABLE;
752 PostEventEx(pQueue, EVENT_SNMP_OK, m_dwId, NULL);
753 SendPollerMsg(dwRqId, POLLER_INFO "Connectivity with SNMP agent restored\r\n");
754 }
755 }
756 else
757 {
758 SendPollerMsg(dwRqId, POLLER_ERROR "SNMP agent unreachable\r\n");
759 if (m_dwDynamicFlags & NDF_SNMP_UNREACHABLE)
760 {
761 if ((tNow > m_tFailTimeSNMP + tExpire) &&
762 (!(m_dwDynamicFlags & NDF_UNREACHABLE)))
763 {
764 m_dwFlags &= ~NF_IS_SNMP;
765 m_dwDynamicFlags &= ~NDF_SNMP_UNREACHABLE;
766 m_szObjectId[0] = 0;
767 SendPollerMsg(dwRqId, POLLER_WARNING "Attribute isSNMP set to FALSE\r\n");
768 }
769 }
770 else
771 {
772 m_dwDynamicFlags |= NDF_SNMP_UNREACHABLE;
773 PostEventEx(pQueue, EVENT_SNMP_FAIL, m_dwId, NULL);
774 m_tFailTimeSNMP = tNow;
775 }
776 }
777 delete pTransport;
778 DbgPrintf(6, "StatusPoll(%s): SNMP check finished", m_szName);
779 }
780
803d47be 781skip_snmp_check:
5039dede 782 // Check native agent connectivity
15d6f8c9 783 if ((m_dwFlags & NF_IS_NATIVE_AGENT) && (!(m_dwFlags & NF_DISABLE_NXCP)) && (m_dwIpAddr != 0))
5039dede 784 {
5039dede
AK
785 DbgPrintf(6, "StatusPoll(%s): checking agent", m_szName);
786 SetPollerInfo(nPoller, "check agent");
787 SendPollerMsg(dwRqId, "Checking NetXMS agent connectivity\r\n");
c3acd0f6
VK
788
789 DWORD error, socketError;
a4569c4d
VK
790 agentLock();
791 if (connectToAgent(&error, &socketError))
5039dede
AK
792 {
793 DbgPrintf(7, "StatusPoll(%s): connected to agent", m_szName);
794 if (m_dwDynamicFlags & NDF_AGENT_UNREACHABLE)
795 {
796 m_dwDynamicFlags &= ~NDF_AGENT_UNREACHABLE;
797 PostEventEx(pQueue, EVENT_AGENT_OK, m_dwId, NULL);
798 SendPollerMsg(dwRqId, POLLER_INFO "Connectivity with NetXMS agent restored\r\n");
799 }
5039dede
AK
800 }
801 else
802 {
c3acd0f6 803 DbgPrintf(6, "StatusPoll(%s): agent unreachable, error=%d, socketError=%d", m_szName, (int)error, (int)socketError);
5039dede
AK
804 SendPollerMsg(dwRqId, POLLER_ERROR "NetXMS agent unreachable\r\n");
805 if (m_dwDynamicFlags & NDF_AGENT_UNREACHABLE)
806 {
807 if ((tNow > m_tFailTimeAgent + tExpire) &&
808 (!(m_dwDynamicFlags & NDF_UNREACHABLE)))
809 {
810 m_dwFlags &= ~NF_IS_NATIVE_AGENT;
811 m_dwDynamicFlags &= ~NDF_AGENT_UNREACHABLE;
812 m_szPlatformName[0] = 0;
813 m_szAgentVersion[0] = 0;
814 SendPollerMsg(dwRqId, POLLER_WARNING "Attribute isNetXMSAgent set to FALSE\r\n");
815 }
816 }
817 else
818 {
819 m_dwDynamicFlags |= NDF_AGENT_UNREACHABLE;
820 PostEventEx(pQueue, EVENT_AGENT_FAIL, m_dwId, NULL);
821 m_tFailTimeAgent = tNow;
822 }
823 }
a4569c4d
VK
824 agentUnlock();
825 DbgPrintf(7, "StatusPoll(%s): agent check finished", m_szName);
5039dede
AK
826 }
827
828 SetPollerInfo(nPoller, "prepare polling list");
829
830 // Find service poller node object
831 LockData();
832 if (m_dwPollerNode != 0)
833 {
834 pPollerNode = FindObjectById(m_dwPollerNode);
835 if (pPollerNode != NULL)
836 {
837 if (pPollerNode->Type() != OBJECT_NODE)
838 pPollerNode = NULL;
839 }
840 }
841 UnlockData();
842
843 // If nothing found, use management server
844 if (pPollerNode == NULL)
845 {
846 pPollerNode = FindObjectById(g_dwMgmtNode);
847 if (pPollerNode != NULL)
848 pPollerNode->IncRefCount();
849 }
850 else
851 {
852 pPollerNode->IncRefCount();
853 }
854
855 // Create polling list
856 ppPollList = (NetObj **)malloc(sizeof(NetObj *) * m_dwChildCount);
857 LockChildList(FALSE);
858 for(i = 0, dwPollListSize = 0; i < m_dwChildCount; i++)
859 if (m_pChildList[i]->Status() != STATUS_UNMANAGED)
860 {
861 m_pChildList[i]->IncRefCount();
862 ppPollList[dwPollListSize++] = m_pChildList[i];
863 }
864 UnlockChildList();
865
866 // Poll interfaces and services
867 SetPollerInfo(nPoller, "child poll");
868 DbgPrintf(7, "StatusPoll(%s): starting child object poll", m_szName);
7c521895 869 pCluster = getMyCluster();
cd9f247e 870 pTransport = createSnmpTransport();
5039dede
AK
871 for(i = 0; i < dwPollListSize; i++)
872 {
873 switch(ppPollList[i]->Type())
874 {
875 case OBJECT_INTERFACE:
876 DbgPrintf(7, "StatusPoll(%s): polling interface %d [%s]", m_szName, ppPollList[i]->Id(), ppPollList[i]->Name());
877 ((Interface *)ppPollList[i])->StatusPoll(pSession, dwRqId, pQueue,
58b3e451 878 (pCluster != NULL) ? pCluster->isSyncAddr(((Interface *)ppPollList[i])->IpAddr()) : FALSE,
5039dede
AK
879 pTransport);
880 break;
881 case OBJECT_NETWORKSERVICE:
882 DbgPrintf(7, "StatusPoll(%s): polling network service %d [%s]", m_szName, ppPollList[i]->Id(), ppPollList[i]->Name());
883 ((NetworkService *)ppPollList[i])->StatusPoll(pSession, dwRqId,
884 (Node *)pPollerNode, pQueue);
885 break;
886 default:
887 break;
888 }
889 ppPollList[i]->DecRefCount();
890 }
891 delete pTransport;
892 safe_free(ppPollList);
893 DbgPrintf(7, "StatusPoll(%s): finished child object poll", m_szName);
894
895 // Check if entire node is down
15d6f8c9
VK
896 // This check is disabled for nodes without IP address
897 if (m_dwIpAddr != 0)
5039dede 898 {
15d6f8c9
VK
899 LockChildList(FALSE);
900 if (m_dwChildCount > 0)
901 {
902 for(i = 0, bAllDown = TRUE; i < m_dwChildCount; i++)
903 if ((m_pChildList[i]->Type() == OBJECT_INTERFACE) &&
904 (m_pChildList[i]->Status() != STATUS_CRITICAL) &&
905 (m_pChildList[i]->Status() != STATUS_UNKNOWN) &&
906 (m_pChildList[i]->Status() != STATUS_UNMANAGED) &&
907 (m_pChildList[i]->Status() != STATUS_DISABLED))
908 {
909 bAllDown = FALSE;
910 break;
911 }
912 }
913 else
914 {
915 bAllDown = FALSE;
916 }
917 UnlockChildList();
918 if (bAllDown && (m_dwFlags & NF_IS_NATIVE_AGENT) &&
919 (!(m_dwFlags & NF_DISABLE_NXCP)))
920 if (!(m_dwDynamicFlags & NDF_AGENT_UNREACHABLE))
921 bAllDown = FALSE;
922 if (bAllDown && (m_dwFlags & NF_IS_SNMP) &&
923 (!(m_dwFlags & NF_DISABLE_SNMP)))
924 if (!(m_dwDynamicFlags & NDF_SNMP_UNREACHABLE))
925 bAllDown = FALSE;
926 if (bAllDown)
927 {
928 if (!(m_dwDynamicFlags & NDF_UNREACHABLE))
929 {
930 m_dwDynamicFlags |= NDF_UNREACHABLE;
931 PostEvent(EVENT_NODE_DOWN, m_dwId, NULL);
932 SendPollerMsg(dwRqId, POLLER_ERROR "Node is unreachable\r\n");
933 }
934 else
935 {
936 SendPollerMsg(dwRqId, POLLER_WARNING "Node is still unreachable\r\n");
937 }
938 }
939 else
940 {
941 if (m_dwDynamicFlags & NDF_UNREACHABLE)
942 {
943 m_dwDynamicFlags &= ~(NDF_UNREACHABLE | NDF_SNMP_UNREACHABLE | NDF_AGENT_UNREACHABLE);
944 PostEvent(EVENT_NODE_UP, m_dwId, NULL);
945 SendPollerMsg(dwRqId, POLLER_INFO "Node recovered from unreachable state\r\n");
946 goto restart_agent_check;
947 }
948 else
949 {
950 SendPollerMsg(dwRqId, POLLER_INFO "Node is connected\r\n");
951 }
952 }
5039dede 953 }
5039dede
AK
954
955 // Send delayed events and destroy delayed event queue
956 ResendEvents(pQueue);
957 delete pQueue;
958
959 SetPollerInfo(nPoller, "cleanup");
960 if (pPollerNode != NULL)
961 pPollerNode->DecRefCount();
962
963 if (dwOldFlags != m_dwFlags)
964 {
965 PostEvent(EVENT_NODE_FLAGS_CHANGED, m_dwId, "xx", dwOldFlags, m_dwFlags);
966 LockData();
967 Modify();
968 UnlockData();
969 }
970
971 CalculateCompoundStatus();
972 m_tLastStatusPoll = time(NULL);
df8a4ca2
VK
973 SendPollerMsg(dwRqId, "Finished status poll for node %s\r\n", m_szName);
974 SendPollerMsg(dwRqId, "Node status after poll is %s\r\n", g_szStatusText[m_iStatus]);
5039dede
AK
975 m_pPollRequestor = NULL;
976 if (dwRqId == 0)
977 m_dwDynamicFlags &= ~NDF_QUEUED_FOR_STATUS_POLL;
7c521895 978 pollerUnlock();
5039dede
AK
979 DbgPrintf(5, "Finished status poll for node %s (ID: %d)", m_szName, m_dwId);
980}
981
982
983//
1f385e47
VK
984// Check agent policy binding
985// Intended to be called only from configuration poller
986//
987
988void Node::checkAgentPolicyBinding(AgentConnection *conn)
989{
990 AgentPolicyInfo *ap;
991 DWORD rcc = conn->getPolicyInventory(&ap);
992 if (rcc == ERR_SUCCESS)
993 {
994 // Check for unbound but installed policies
995 for(int i = 0; i < ap->getSize(); i++)
996 {
997 uuid_t guid;
998 ap->getGuid(i, guid);
999 NetObj *object = FindObjectByGUID(guid, -1);
1000 if ((object != NULL) && (!object->IsChild(m_dwId)))
1001 {
1002 object->AddChild(this);
1003 AddParent(object);
1004 DbgPrintf(5, _T("ConfPoll(%s): bound to policy object %s [%d]"), m_szName, object->Name(), object->Id());
1005 }
1006 }
1007
1008 // Check for bound but not installed policies
1009 LockParentList(FALSE);
1010 NetObj **unbindList = (NetObj **)malloc(sizeof(NetObj *) * m_dwParentCount);
1011 int unbindListSize = 0;
1012 for(DWORD i = 0; i < m_dwParentCount; i++)
1013 {
1014 if (IsAgentPolicyObject(m_pParentList[i]))
1015 {
1016 uuid_t guid1, guid2;
1017 int j;
1018
1019 m_pParentList[i]->getGuid(guid1);
1020 for(j = 0; j < ap->getSize(); j++)
1021 {
1022 ap->getGuid(j, guid2);
1023 if (!uuid_compare(guid1, guid2))
1024 break;
1025 }
1026 if (j == ap->getSize())
1027 unbindList[unbindListSize++] = m_pParentList[i];
1028 }
1029 }
1030 UnlockParentList();
1031
1032 for(int i = 0; i < unbindListSize; i++)
1033 {
1034 unbindList[i]->DeleteChild(this);
1035 DeleteParent(unbindList[i]);
1036 DbgPrintf(5, _T("ConfPoll(%s): unbound from policy object %s [%d]"), m_szName, unbindList[i]->Name(), unbindList[i]->Id());
1037 }
1038 safe_free(unbindList);
1039
1040 delete ap;
1041 }
1042 else
1043 {
1044 DbgPrintf(5, _T("ConfPoll(%s): AgentConnection::getPolicyInventory() failed: rcc=%d"), m_szName, rcc);
1045 }
1046}
1047
1048
1049//
5039dede
AK
1050// Perform configuration poll on node
1051//
1052
58b3e451 1053void Node::configurationPoll(ClientSession *pSession, DWORD dwRqId,
5039dede
AK
1054 int nPoller, DWORD dwNetMask)
1055{
1056 DWORD i, dwOldFlags = m_dwFlags, dwAddr, rcc, dwNumParams;
1057 NXC_AGENT_PARAM *pParamList;
1058 Interface **ppDeleteList;
1059 int j, iDelCount;
1060 AgentConnection *pAgentConn;
1061 INTERFACE_LIST *pIfList;
1062 char szBuffer[4096];
1063 Cluster *pCluster;
1064 SNMP_Transport *pTransport;
5039dede
AK
1065 BOOL bHasChanges = FALSE;
1066
1067 SetPollerInfo(nPoller, "wait for lock");
7c521895 1068 pollerLock();
5039dede
AK
1069 m_pPollRequestor = pSession;
1070 SendPollerMsg(dwRqId, _T("Starting configuration poll for node %s\r\n"), m_szName);
1071 DbgPrintf(4, "Starting configuration poll for node %s (ID: %d)", m_szName, m_dwId);
1072
1073 // Check for forced capabilities recheck
1074 if (m_dwDynamicFlags & NDF_RECHECK_CAPABILITIES)
1075 {
1076 m_dwFlags &= ~(NF_IS_NATIVE_AGENT | NF_IS_SNMP | NF_IS_CPSNMP |
1077 NF_IS_BRIDGE | NF_IS_ROUTER | NF_IS_OSPF);
e4a64da2 1078 m_dwDynamicFlags &= ~NDF_CONFIGURATION_POLL_PASSED;
5039dede
AK
1079 m_szObjectId[0] = 0;
1080 m_szPlatformName[0] = 0;
1081 m_szAgentVersion[0] = 0;
1082 m_szSysDescription[0] = 0;
1083 }
1084
1085 // Check if node is marked as unreachable
1086 if ((m_dwDynamicFlags & NDF_UNREACHABLE) && !(m_dwDynamicFlags & NDF_RECHECK_CAPABILITIES))
1087 {
1088 SendPollerMsg(dwRqId, POLLER_WARNING _T("Node is marked as unreachable, configuration poll aborted\r\n"));
1089 DbgPrintf(4, "Node is marked as unreachable, configuration poll aborted");
1090 m_tLastConfigurationPoll = time(NULL);
1091 }
1092 else
1093 {
1094 // Check node's capabilities
1095 SetPollerInfo(nPoller, "capability check");
1096 SendPollerMsg(dwRqId, _T("Checking node's capabilities...\r\n"));
1097
1098 // ***** NetXMS agent check *****
1099 DbgPrintf(5, "ConfPoll(%s): checking for NetXMS agent Flags={%08X} DynamicFlags={%08X}", m_szName, m_dwFlags, m_dwDynamicFlags);
1100 if ((!((m_dwFlags & NF_IS_NATIVE_AGENT) && (m_dwDynamicFlags & NDF_AGENT_UNREACHABLE))) &&
15d6f8c9 1101 (!(m_dwFlags & NF_DISABLE_NXCP)) && (m_dwIpAddr != 0))
5039dede
AK
1102 {
1103 SendPollerMsg(dwRqId, _T(" Checking NetXMS agent...\r\n"));
1104 pAgentConn = new AgentConnection(htonl(m_dwIpAddr), m_wAgentPort,
1105 m_wAuthMethod, m_szSharedSecret);
7c521895 1106 setAgentProxy(pAgentConn);
5039dede 1107 DbgPrintf(5, "ConfPoll(%s): checking for NetXMS agent - connecting", m_szName);
7c521895 1108 if (pAgentConn->connect(g_pServerKey))
5039dede
AK
1109 {
1110 DbgPrintf(5, "ConfPoll(%s): checking for NetXMS agent - connected", m_szName);
1111 LockData();
1112 m_dwFlags |= NF_IS_NATIVE_AGENT;
1113 if (m_dwDynamicFlags & NDF_AGENT_UNREACHABLE)
1114 {
1115 m_dwDynamicFlags &= ~NDF_AGENT_UNREACHABLE;
1116 PostEvent(EVENT_AGENT_OK, m_dwId, NULL);
1117 SendPollerMsg(dwRqId, POLLER_INFO _T(" Connectivity with NetXMS agent restored\r\n"));
1118 }
1f385e47
VK
1119 else
1120 {
1121 SendPollerMsg(dwRqId, POLLER_INFO _T(" NetXMS native agent is active\r\n"));
1122 }
5039dede
AK
1123 UnlockData();
1124
1125 if (pAgentConn->GetParameter("Agent.Version", MAX_AGENT_VERSION_LEN, szBuffer) == ERR_SUCCESS)
1126 {
1127 LockData();
1128 if (strcmp(m_szAgentVersion, szBuffer))
1129 {
1130 strcpy(m_szAgentVersion, szBuffer);
1131 bHasChanges = TRUE;
1132 SendPollerMsg(dwRqId, _T(" NetXMS agent version changed to %s\r\n"), m_szAgentVersion);
1133 }
1134 UnlockData();
1135 }
1136
1137 if (pAgentConn->GetParameter("System.PlatformName", MAX_PLATFORM_NAME_LEN, szBuffer) == ERR_SUCCESS)
1138 {
1139 LockData();
1140 if (strcmp(m_szPlatformName, szBuffer))
1141 {
1142 strcpy(m_szPlatformName, szBuffer);
1143 bHasChanges = TRUE;
1144 SendPollerMsg(dwRqId, _T(" Platform name changed to %s\r\n"), m_szPlatformName);
1145 }
1146 UnlockData();
1147 }
1148
1149 // Check IP forwarding status
1150 if (pAgentConn->GetParameter("Net.IP.Forwarding", 16, szBuffer) == ERR_SUCCESS)
1151 {
1152 if (_tcstoul(szBuffer, NULL, 10) != 0)
1153 m_dwFlags |= NF_IS_ROUTER;
1154 else
1155 m_dwFlags &= ~NF_IS_ROUTER;
1156 }
1157
1158 // Get uname
1159 if (pAgentConn->GetParameter("System.Uname", MAX_DB_STRING, szBuffer) == ERR_SUCCESS)
1160 {
1161 TranslateStr(szBuffer, "\r\n", " ");
1162 TranslateStr(szBuffer, "\n", " ");
1163 TranslateStr(szBuffer, "\r", " ");
1164 LockData();
1165 if (strcmp(m_szSysDescription, szBuffer))
1166 {
1167 strcpy(m_szSysDescription, szBuffer);
1168 bHasChanges = TRUE;
1169 SendPollerMsg(dwRqId, _T(" System description changed to %s\r\n"), m_szSysDescription);
1170 }
1171 UnlockData();
1172 }
1173
1174 rcc = pAgentConn->GetSupportedParameters(&dwNumParams, &pParamList);
1175 if (rcc == ERR_SUCCESS)
1176 {
1177 LockData();
1178 safe_free(m_pParamList);
1179 m_dwNumParams = dwNumParams;
1180 m_pParamList = pParamList;
1181 UnlockData();
1182 }
1183 else
1184 {
1185 DbgPrintf(5, _T("ConfPoll(%s): AgentConnection::GetSupportedParameters() failed: rcc=%d"), m_szName, rcc);
1186 }
1187
1f385e47
VK
1188 checkAgentPolicyBinding(pAgentConn);
1189
7c521895 1190 pAgentConn->disconnect();
5039dede
AK
1191 }
1192 delete pAgentConn;
1193 DbgPrintf(5, "ConfPoll(%s): checking for NetXMS agent - finished", m_szName);
1194 }
1195
1196 // ***** SNMP check *****
1197 if ((!((m_dwFlags & NF_IS_SNMP) && (m_dwDynamicFlags & NDF_SNMP_UNREACHABLE))) &&
15d6f8c9 1198 (!(m_dwFlags & NF_DISABLE_SNMP)) && (m_dwIpAddr != 0))
5039dede
AK
1199 {
1200 SendPollerMsg(dwRqId, _T(" Checking SNMP...\r\n"));
df8a4ca2 1201 DbgPrintf(5, "ConfPoll(%s): calling SnmpCheckCommSettings()", m_szName);
cd9f247e 1202 pTransport = createSnmpTransport();
f2ec1aae
VK
1203 if (pTransport == NULL)
1204 {
1205 DbgPrintf(5, "ConfPoll(%s): unable to create SNMP transport", m_szName);
1206 goto skip_snmp_checks;
1207 }
5039dede 1208
df8a4ca2
VK
1209 SNMP_SecurityContext *newCtx = SnmpCheckCommSettings(pTransport, &m_snmpVersion, m_snmpSecurity);
1210 if (newCtx != NULL)
5039dede
AK
1211 {
1212 DWORD dwNodeFlags, dwNodeType;
1213
1214 LockData();
df8a4ca2
VK
1215 delete m_snmpSecurity;
1216 m_snmpSecurity = newCtx;
5039dede
AK
1217 m_dwFlags |= NF_IS_SNMP;
1218 if (m_dwDynamicFlags & NDF_SNMP_UNREACHABLE)
1219 {
1220 m_dwDynamicFlags &= ~NDF_SNMP_UNREACHABLE;
1221 PostEvent(EVENT_SNMP_OK, m_dwId, NULL);
df8a4ca2 1222 SendPollerMsg(dwRqId, POLLER_INFO _T(" Connectivity with SNMP agent restored\r\n"));
5039dede
AK
1223 }
1224 UnlockData();
df8a4ca2
VK
1225 SendPollerMsg(dwRqId, _T(" SNMP agent is active (version %s)\r\n"),
1226 (m_snmpVersion == SNMP_VERSION_3) ? _T("3") : ((m_snmpVersion == SNMP_VERSION_2C) ? _T("2c") : _T("1")));
5039dede 1227
5d2c5741 1228 if (SnmpGet(m_snmpVersion, pTransport,
5039dede
AK
1229 ".1.3.6.1.2.1.1.2.0", NULL, 0, szBuffer, 4096,
1230 FALSE, FALSE) == SNMP_ERR_SUCCESS)
1231 {
1232 LockData();
1233 if (strcmp(m_szObjectId, szBuffer))
1234 {
1235 nx_strncpy(m_szObjectId, szBuffer, MAX_OID_LEN * 4);
1236 bHasChanges = TRUE;
1237 }
1238 UnlockData();
1239 }
1240
1241 // Check node type
1242 LockData();
1243 dwNodeType = OidToType(m_szObjectId, &dwNodeFlags);
1244 if (m_dwNodeType != dwNodeType)
1245 {
1246 m_dwFlags |= dwNodeFlags;
1247 m_dwNodeType = dwNodeType;
1248 SendPollerMsg(dwRqId, POLLER_WARNING _T(" Node type has been changed to %d\r\n"), m_dwNodeType);
1249 bHasChanges = TRUE;
1250 }
1251 UnlockData();
1252
1253 // Check IP forwarding
1254 if (CheckSNMPIntegerValue(pTransport, ".1.3.6.1.2.1.4.1.0", 1))
1255 {
1256 LockData();
1257 m_dwFlags |= NF_IS_ROUTER;
1258 UnlockData();
1259 }
1260 else
1261 {
1262 LockData();
1263 m_dwFlags &= ~NF_IS_ROUTER;
1264 UnlockData();
1265 }
1266
1267 // Check for bridge MIB support
5d2c5741 1268 if (SnmpGet(m_snmpVersion, pTransport,
5039dede
AK
1269 ".1.3.6.1.2.1.17.1.1.0", NULL, 0, szBuffer, 4096,
1270 FALSE, FALSE) == SNMP_ERR_SUCCESS)
1271 {
1272 LockData();
1273 m_dwFlags |= NF_IS_BRIDGE;
1274 UnlockData();
1275 }
1276 else
1277 {
1278 LockData();
1279 m_dwFlags &= ~NF_IS_BRIDGE;
1280 UnlockData();
1281 }
1282
1283 // Check for CDP (Cisco Discovery Protocol) support
1284 if (CheckSNMPIntegerValue(pTransport, ".1.3.6.1.4.1.9.9.23.1.3.1.0", 1))
1285 {
1286 LockData();
1287 m_dwFlags |= NF_IS_CDP;
1288 UnlockData();
1289 }
1290 else
1291 {
1292 LockData();
1293 m_dwFlags &= ~NF_IS_CDP;
1294 UnlockData();
1295 }
1296
1297 // Check for SONMP (Nortel topology discovery discovery protocol) support
1298 if (CheckSNMPIntegerValue(pTransport, ".1.3.6.1.4.1.45.1.6.13.1.2.0", 1))
1299 {
1300 LockData();
1301 m_dwFlags |= NF_IS_SONMP;
1302 UnlockData();
1303 }
1304 else
1305 {
1306 LockData();
1307 m_dwFlags &= ~NF_IS_SONMP;
1308 UnlockData();
1309 }
1310
1311 // Check for LLDP (Link Layer Discovery Protocol) support
5d2c5741 1312 if (SnmpGet(m_snmpVersion, pTransport,
5039dede
AK
1313 ".1.0.8802.1.1.2.1.3.2.0", NULL, 0, szBuffer, 4096,
1314 FALSE, FALSE) == SNMP_ERR_SUCCESS)
1315 {
1316 LockData();
1317 m_dwFlags |= NF_IS_LLDP;
1318 UnlockData();
1319 }
1320 else
1321 {
1322 LockData();
1323 m_dwFlags &= ~NF_IS_LLDP;
1324 UnlockData();
1325 }
1326
1327 // Get system description
5d2c5741 1328 if (SnmpGet(m_snmpVersion, pTransport,
5039dede
AK
1329 ".1.3.6.1.2.1.1.1.0", NULL, 0, szBuffer,
1330 MAX_DB_STRING, FALSE, FALSE) == SNMP_ERR_SUCCESS)
1331 {
1332 TranslateStr(szBuffer, "\r\n", " ");
1333 TranslateStr(szBuffer, "\n", " ");
1334 TranslateStr(szBuffer, "\r", " ");
1335 LockData();
1336 if (strcmp(m_szSysDescription, szBuffer))
1337 {
1338 strcpy(m_szSysDescription, szBuffer);
1339 bHasChanges = TRUE;
1340 SendPollerMsg(dwRqId, _T(" System description changed to %s\r\n"), m_szSysDescription);
1341 }
1342 UnlockData();
1343 }
1344
1345 CheckOSPFSupport(pTransport);
1346 }
1347 else
1348 {
1349 // Check for CheckPoint SNMP agent on port 161
1350 DbgPrintf(5, "ConfPoll(%s): checking for CheckPoint SNMP", m_szName);
5d2c5741 1351 if (SnmpGet(m_snmpVersion, pTransport,
5039dede
AK
1352 ".1.3.6.1.4.1.2620.1.1.10.0", NULL, 0,
1353 szBuffer, 4096, FALSE, FALSE) == SNMP_ERR_SUCCESS)
1354 {
1355 LockData();
1356 if (strcmp(m_szObjectId, ".1.3.6.1.4.1.2620.1.1"))
1357 {
1358 nx_strncpy(m_szObjectId, ".1.3.6.1.4.1.2620.1.1", MAX_OID_LEN * 4);
1359 bHasChanges = TRUE;
1360 }
1361
1362 m_dwFlags |= NF_IS_SNMP | NF_IS_ROUTER;
1363 m_dwDynamicFlags &= ~NDF_SNMP_UNREACHABLE;
1364 UnlockData();
1365 SendPollerMsg(dwRqId, POLLER_INFO _T(" CheckPoint SNMP agent on port 161 is active\r\n"));
1366 }
1367 }
1368 delete pTransport;
1369 }
1370
f2ec1aae 1371skip_snmp_checks:
5039dede
AK
1372 // Check for CheckPoint SNMP agent on port 260
1373 DbgPrintf(5, "ConfPoll(%s): checking for CheckPoint SNMP on port 260", m_szName);
15d6f8c9 1374 if (!((m_dwFlags & NF_IS_CPSNMP) && (m_dwDynamicFlags & NDF_CPSNMP_UNREACHABLE)) && (m_dwIpAddr != 0))
5039dede
AK
1375 {
1376 pTransport = new SNMP_UDPTransport;
c4366266 1377 ((SNMP_UDPTransport *)pTransport)->createUDPTransport(NULL, htonl(m_dwIpAddr), CHECKPOINT_SNMP_PORT);
5d2c5741 1378 if (SnmpGet(SNMP_VERSION_1, pTransport,
5039dede
AK
1379 ".1.3.6.1.4.1.2620.1.1.10.0", NULL, 0,
1380 szBuffer, 4096, FALSE, FALSE) == SNMP_ERR_SUCCESS)
1381 {
1382 LockData();
1383 m_dwFlags |= NF_IS_CPSNMP | NF_IS_ROUTER;
1384 m_dwDynamicFlags &= ~NDF_CPSNMP_UNREACHABLE;
1385 UnlockData();
1386 SendPollerMsg(dwRqId, POLLER_INFO _T(" CheckPoint SNMP agent on port 260 is active\r\n"));
1387 }
1388 delete pTransport;
1389 }
1390
1391 // Generate event if node flags has been changed
1392 if (dwOldFlags != m_dwFlags)
1393 {
1394 PostEvent(EVENT_NODE_FLAGS_CHANGED, m_dwId, "xx", dwOldFlags, m_dwFlags);
1395 bHasChanges = TRUE;
1396 }
1397
1398 // Get parent cluster object, if any
7c521895 1399 pCluster = getMyCluster();
5039dede
AK
1400
1401 // Retrieve interface list
1402 SetPollerInfo(nPoller, "interface check");
df8a4ca2
VK
1403 SendPollerMsg(dwRqId, _T("Capability check finished\r\n"));
1404 SendPollerMsg(dwRqId, _T("Checking interface configuration...\r\n"));
58b3e451 1405 pIfList = getInterfaceList();
5039dede
AK
1406 if (pIfList != NULL)
1407 {
1408 // Remove cluster virtual interfaces from list
1409 if (pCluster != NULL)
1410 {
1411 for(i = 0; i < (DWORD)pIfList->iNumEntries; i++)
1412 {
58b3e451 1413 if (pCluster->isVirtualAddr(pIfList->pInterfaces[i].dwIpAddr))
5039dede
AK
1414 {
1415 pIfList->iNumEntries--;
1416 memmove(&pIfList->pInterfaces[i], &pIfList->pInterfaces[i + 1],
1417 sizeof(INTERFACE_INFO) * (pIfList->iNumEntries - i));
1418 i--;
1419 }
1420 }
1421 }
1422
1423 // Find non-existing interfaces
1424 LockChildList(FALSE);
1425 ppDeleteList = (Interface **)malloc(sizeof(Interface *) * m_dwChildCount);
1426 for(i = 0, iDelCount = 0; i < m_dwChildCount; i++)
1427 {
1428 if (m_pChildList[i]->Type() == OBJECT_INTERFACE)
1429 {
1430 Interface *pInterface = (Interface *)m_pChildList[i];
1431
1432 if (pInterface->IfType() != IFTYPE_NETXMS_NAT_ADAPTER)
1433 {
1434 for(j = 0; j < pIfList->iNumEntries; j++)
1435 {
1436 if ((pIfList->pInterfaces[j].dwIndex == pInterface->IfIndex()) &&
1437 (pIfList->pInterfaces[j].dwIpAddr == pInterface->IpAddr()) &&
1438 (pIfList->pInterfaces[j].dwIpNetMask == pInterface->IpNetMask()))
1439 break;
1440 }
1441
1442 if (j == pIfList->iNumEntries)
1443 {
1444 // No such interface in current configuration, add it to delete list
1445 ppDeleteList[iDelCount++] = pInterface;
1446 }
1447 }
1448 }
1449 }
1450 UnlockChildList();
1451
1452 // Delete non-existent interfaces
1453 if (iDelCount > 0)
1454 {
1455 for(j = 0; j < iDelCount; j++)
1456 {
1457 SendPollerMsg(dwRqId, POLLER_WARNING _T(" Interface \"%s\" is no longer exist\r\n"),
1458 ppDeleteList[j]->Name());
1459 PostEvent(EVENT_INTERFACE_DELETED, m_dwId, "dsaa", ppDeleteList[j]->IfIndex(),
1460 ppDeleteList[j]->Name(), ppDeleteList[j]->IpAddr(), ppDeleteList[j]->IpNetMask());
1461 DeleteInterface(ppDeleteList[j]);
1462 }
1463 bHasChanges = TRUE;
1464 }
1465 safe_free(ppDeleteList);
1466
1467 // Add new interfaces and check configuration of existing
1468 for(j = 0; j < pIfList->iNumEntries; j++)
1469 {
1470 BOOL bNewInterface = TRUE;
1471
1472 LockChildList(FALSE);
1473 for(i = 0; i < m_dwChildCount; i++)
1474 {
1475 if (m_pChildList[i]->Type() == OBJECT_INTERFACE)
1476 {
1477 Interface *pInterface = (Interface *)m_pChildList[i];
1478
1479 if ((pIfList->pInterfaces[j].dwIndex == pInterface->IfIndex()) &&
1480 (pIfList->pInterfaces[j].dwIpAddr == pInterface->IpAddr()) &&
1481 (pIfList->pInterfaces[j].dwIpNetMask == pInterface->IpNetMask()))
1482 {
1483 // Existing interface, check configuration
1484 if (memcmp(pIfList->pInterfaces[j].bMacAddr, pInterface->MacAddr(), MAC_ADDR_LENGTH))
1485 {
1486 char szOldMac[16], szNewMac[16];
1487
1488 BinToStr((BYTE *)pInterface->MacAddr(), MAC_ADDR_LENGTH, szOldMac);
1489 BinToStr(pIfList->pInterfaces[j].bMacAddr, MAC_ADDR_LENGTH, szNewMac);
1490 PostEvent(EVENT_MAC_ADDR_CHANGED, m_dwId, "idsss",
1491 pInterface->Id(), pInterface->IfIndex(),
1492 pInterface->Name(), szOldMac, szNewMac);
1493 pInterface->SetMacAddr(pIfList->pInterfaces[j].bMacAddr);
1494 }
1495 if (strcmp(pIfList->pInterfaces[j].szName, pInterface->Name()))
1496 {
1497 pInterface->SetName(pIfList->pInterfaces[j].szName);
1498 }
1499 bNewInterface = FALSE;
1500 break;
1501 }
1502 }
1503 }
1504 UnlockChildList();
1505
1506 if (bNewInterface)
1507 {
1508 // New interface
1509 SendPollerMsg(dwRqId, POLLER_INFO _T(" Found new interface \"%s\"\r\n"),
1510 pIfList->pInterfaces[j].szName);
1511 CreateNewInterface(pIfList->pInterfaces[j].dwIpAddr,
1512 pIfList->pInterfaces[j].dwIpNetMask,
1513 pIfList->pInterfaces[j].szName,
1514 pIfList->pInterfaces[j].dwIndex,
1515 pIfList->pInterfaces[j].dwType,
1516 pIfList->pInterfaces[j].bMacAddr);
1517 bHasChanges = TRUE;
1518 }
1519 }
1520
1521 // Check if address we are using to communicate with node
1522 // is configured on one of node's interfaces
1523 for(i = 0; i < (DWORD)pIfList->iNumEntries; i++)
1524 if (pIfList->pInterfaces[i].dwIpAddr == m_dwIpAddr)
1525 break;
1526
1527 if (i == (DWORD)pIfList->iNumEntries)
1528 {
1529 BOOL bCreate = TRUE;
1530
1531 // Node is behind NAT
1532 m_dwFlags |= NF_BEHIND_NAT;
1533
1534 // Check if we already have NAT interface
1535 LockChildList(FALSE);
1536 for(i = 0; i < m_dwChildCount; i++)
1537 if (m_pChildList[i]->Type() == OBJECT_INTERFACE)
1538 {
1539 if (((Interface *)m_pChildList[i])->IfType() == IFTYPE_NETXMS_NAT_ADAPTER)
1540 {
1541 bCreate = FALSE;
1542 break;
1543 }
1544 }
1545 UnlockChildList();
1546
1547 if (bCreate)
1548 {
1549 char szBuffer[MAX_OBJECT_NAME];
1550
1551 // Create pseudo interface for NAT
1552 ConfigReadStr("NATAdapterName", szBuffer, MAX_OBJECT_NAME, "NetXMS NAT Adapter");
1553 CreateNewInterface(m_dwIpAddr, 0, szBuffer,
1554 0x7FFFFFFF, IFTYPE_NETXMS_NAT_ADAPTER);
1555 bHasChanges = TRUE;
1556 }
1557 }
1558 else
1559 {
1560 // Check if NF_BEHIND_NAT flag set incorrectly
1561 if (m_dwFlags & NF_BEHIND_NAT)
1562 {
1563 Interface *pIfNat;
1564
1565 // Remove NAT interface
1566 LockChildList(FALSE);
1567 for(i = 0, pIfNat = NULL; i < m_dwChildCount; i++)
1568 if (m_pChildList[i]->Type() == OBJECT_INTERFACE)
1569 {
1570 if (((Interface *)m_pChildList[i])->IfType() == IFTYPE_NETXMS_NAT_ADAPTER)
1571 {
1572 pIfNat = (Interface *)m_pChildList[i];
1573 break;
1574 }
1575 }
1576 UnlockChildList();
1577
1578 if (pIfNat != NULL)
1579 DeleteInterface(pIfNat);
1580
1581 m_dwFlags &= ~NF_BEHIND_NAT;
1582 bHasChanges = TRUE;
1583 }
1584 }
1585
1586 CheckSubnetBinding(pIfList);
1587
1588 DestroyInterfaceList(pIfList);
1589 }
1590 else /* pIfList == NULL */
1591 {
1592 Interface *pInterface;
1593 DWORD dwCount;
1594
1595 SendPollerMsg(dwRqId, POLLER_ERROR _T("Unable to get interface list from node\r\n"));
1596
1597 // Delete all existing interfaces in case of forced capability recheck
1598 if (m_dwDynamicFlags & NDF_RECHECK_CAPABILITIES)
1599 {
1600 LockChildList(FALSE);
1601 ppDeleteList = (Interface **)malloc(sizeof(Interface *) * m_dwChildCount);
1602 for(i = 0, iDelCount = 0; i < m_dwChildCount; i++)
1603 {
1604 if (m_pChildList[i]->Type() == OBJECT_INTERFACE)
1605 ppDeleteList[iDelCount++] = (Interface *)m_pChildList[i];
1606 }
1607 UnlockChildList();
1608 for(j = 0; j < iDelCount; j++)
1609 {
1610 SendPollerMsg(dwRqId, POLLER_WARNING _T(" Interface \"%s\" is no longer exist\r\n"),
1611 ppDeleteList[j]->Name());
1612 PostEvent(EVENT_INTERFACE_DELETED, m_dwId, "dsaa", ppDeleteList[j]->IfIndex(),
1613 ppDeleteList[j]->Name(), ppDeleteList[j]->IpAddr(), ppDeleteList[j]->IpNetMask());
1614 DeleteInterface(ppDeleteList[j]);
1615 }
1616 safe_free(ppDeleteList);
1617 }
1618
1619 // Check if we have pseudo-interface object
7c521895 1620 dwCount = getInterfaceCount(&pInterface);
5039dede
AK
1621 if (dwCount == 1)
1622 {
1623 if (pInterface->IsFake())
1624 {
1625 // Check if primary IP is different from interface's IP
1626 if (pInterface->IpAddr() != m_dwIpAddr)
1627 {
1628 DeleteInterface(pInterface);
15d6f8c9
VK
1629 if (m_dwIpAddr != 0)
1630 CreateNewInterface(m_dwIpAddr, dwNetMask);
5039dede
AK
1631 }
1632 }
1633 }
1634 else if (dwCount == 0)
1635 {
1636 // No interfaces at all, create pseudo-interface
15d6f8c9
VK
1637 if (m_dwIpAddr != 0)
1638 CreateNewInterface(m_dwIpAddr, dwNetMask);
5039dede
AK
1639 }
1640 }
1641
1642 m_tLastConfigurationPoll = time(NULL);
1643 SendPollerMsg(dwRqId, _T("Interface configuration check finished\r\n"));
1644
1645 // Check node name
1646 SendPollerMsg(dwRqId, _T("Checking node name\r\n"));
1647 dwAddr = ntohl(_t_inet_addr(m_szName));
1648 if ((g_dwFlags & AF_RESOLVE_NODE_NAMES) &&
1649 (dwAddr != INADDR_NONE) &&
1650 (dwAddr != INADDR_ANY) &&
58b3e451 1651 isMyIP(dwAddr))
5039dede
AK
1652 {
1653 SendPollerMsg(dwRqId, _T("Node name is an IP address and need to be resolved\r\n"));
1654 SetPollerInfo(nPoller, "resolving name");
1655 if (ResolveName(FALSE))
1656 {
1657 SendPollerMsg(dwRqId, POLLER_INFO _T("Node name resolved to %s\r\n"), m_szName);
1658 bHasChanges = TRUE;
1659 }
1660 else
1661 {
1662 SendPollerMsg(dwRqId, POLLER_WARNING _T("Node name cannot be resolved\r\n"));
1663 }
1664 }
1665 else
1666 {
1667 if (g_dwFlags & AF_SYNC_NODE_NAMES_WITH_DNS)
1668 {
1669 SendPollerMsg(dwRqId, _T("Syncing node name with DNS\r\n"));
1670 SetPollerInfo(nPoller, "resolving name");
1671 if (ResolveName(TRUE))
1672 {
1673 SendPollerMsg(dwRqId, POLLER_INFO _T("Node name resolved to %s\r\n"), m_szName);
1674 bHasChanges = TRUE;
1675 }
1676 }
1677 else
1678 {
1679 SendPollerMsg(dwRqId, _T("Node name is OK\r\n"));
1680 }
1681 }
1682
4d0c32f3
VK
1683 // Apply templates
1684 ApplySystemTemplates();
1685 ApplyUserTemplates();
1686
7c521895 1687 updateContainerMembership();
4d0c32f3 1688
df8a4ca2
VK
1689 SendPollerMsg(dwRqId, _T("Finished configuration poll for node %s\r\n"), m_szName);
1690 SendPollerMsg(dwRqId, _T("Node configuration was%schanged after poll\r\n"), bHasChanges ? _T(" ") : _T(" not "));
e4a64da2
VK
1691
1692 m_dwDynamicFlags |= NDF_CONFIGURATION_POLL_PASSED;
4d0c32f3
VK
1693 }
1694
1695 // Finish configuration poll
1696 SetPollerInfo(nPoller, "cleanup");
1697 if (dwRqId == 0)
1698 m_dwDynamicFlags &= ~NDF_QUEUED_FOR_CONFIG_POLL;
1699 m_dwDynamicFlags &= ~NDF_RECHECK_CAPABILITIES;
7c521895 1700 pollerUnlock();
4d0c32f3
VK
1701 DbgPrintf(4, "Finished configuration poll for node %s (ID: %d)", m_szName, m_dwId);
1702
1703 if (bHasChanges)
1704 {
1705 LockData();
1706 Modify();
1707 UnlockData();
1708 }
1709}
1710
1711
1712//
1713// Apply system templates
1714//
1715
1716void Node::ApplySystemTemplates()
1717{
1718 Template *pTemplate;
1719
1720 pTemplate = FindTemplateByName(_T("@System.Agent"));
1721 if (pTemplate != NULL)
1722 {
7c521895 1723 if (isNativeAgent())
5039dede 1724 {
4d0c32f3 1725 if (!pTemplate->IsChild(m_dwId))
5039dede 1726 {
4d0c32f3
VK
1727 DbgPrintf(4, _T("Node::ApplySystemTemplates(): applying template %d \"%s\" to node %d \"%s\""),
1728 pTemplate->Id(), pTemplate->Name(), m_dwId, m_szName);
1729 pTemplate->ApplyToNode(this);
5039dede 1730 }
4d0c32f3
VK
1731 }
1732 else
1733 {
1734 if (pTemplate->IsChild(m_dwId))
5039dede 1735 {
4d0c32f3
VK
1736 DbgPrintf(4, _T("Node::ApplySystemTemplates(): removing template %d \"%s\" from node %d \"%s\""),
1737 pTemplate->Id(), pTemplate->Name(), m_dwId, m_szName);
1738 pTemplate->DeleteChild(this);
1739 DeleteParent(pTemplate);
fb05c05b 1740 pTemplate->queueRemoveFromNode(m_dwId, TRUE);
5039dede
AK
1741 }
1742 }
4d0c32f3 1743 }
5039dede 1744
4d0c32f3
VK
1745 pTemplate = FindTemplateByName(_T("@System.SNMP"));
1746 if (pTemplate != NULL)
1747 {
7c521895 1748 if (isSNMPSupported())
4d0c32f3
VK
1749 {
1750 if (!pTemplate->IsChild(m_dwId))
1751 {
1752 DbgPrintf(4, _T("Node::ApplySystemTemplates(): applying template %d \"%s\" to node %d \"%s\""),
1753 pTemplate->Id(), pTemplate->Name(), m_dwId, m_szName);
1754 pTemplate->ApplyToNode(this);
1755 }
1756 }
1757 else
5039dede 1758 {
4d0c32f3
VK
1759 if (pTemplate->IsChild(m_dwId))
1760 {
1761 DbgPrintf(4, _T("Node::ApplySystemTemplates(): removing template %d \"%s\" from node %d \"%s\""),
1762 pTemplate->Id(), pTemplate->Name(), m_dwId, m_szName);
1763 pTemplate->DeleteChild(this);
1764 DeleteParent(pTemplate);
fb05c05b 1765 pTemplate->queueRemoveFromNode(m_dwId, TRUE);
4d0c32f3
VK
1766 }
1767 }
1768 }
1769}
1770
1771
1772//
1773// Apply user templates
1774//
1775
1776void Node::ApplyUserTemplates()
1777{
1778 DWORD i;
1779 Template *pTemplate;
1780
1781 if (g_pIndexById == NULL)
1782 return;
1783
1784 RWLockReadLock(g_rwlockIdIndex, INFINITE);
1785 for(i = 0; i < g_dwIdIndexSize; i++)
1786 {
1787 if ((((NetObj *)g_pIndexById[i].pObject)->Type() == OBJECT_TEMPLATE) &&
1788 (!((NetObj *)g_pIndexById[i].pObject)->IsDeleted()))
1789 {
1790 pTemplate = (Template *)g_pIndexById[i].pObject;
fb05c05b 1791 if (pTemplate->isApplicable(this))
5039dede
AK
1792 {
1793 if (!pTemplate->IsChild(m_dwId))
1794 {
4d0c32f3
VK
1795 DbgPrintf(4, _T("Node::ApplyUserTemplates(): applying template %d \"%s\" to node %d \"%s\""),
1796 pTemplate->Id(), pTemplate->Name(), m_dwId, m_szName);
5039dede
AK
1797 pTemplate->ApplyToNode(this);
1798 }
1799 }
1800 else
1801 {
fb05c05b 1802 if (pTemplate->isAutoApplyEnabled() && pTemplate->IsChild(m_dwId))
5039dede 1803 {
4d0c32f3
VK
1804 DbgPrintf(4, _T("Node::ApplyUserTemplates(): removing template %d \"%s\" from node %d \"%s\""),
1805 pTemplate->Id(), pTemplate->Name(), m_dwId, m_szName);
5039dede
AK
1806 pTemplate->DeleteChild(this);
1807 DeleteParent(pTemplate);
fb05c05b 1808 pTemplate->queueRemoveFromNode(m_dwId, TRUE);
5039dede
AK
1809 }
1810 }
4d0c32f3 1811 }
5039dede 1812 }
4d0c32f3
VK
1813 RWLockUnlock(g_rwlockIdIndex);
1814}
5039dede 1815
5039dede 1816
4d0c32f3
VK
1817//
1818// Update container membership
1819//
1820
7c521895 1821void Node::updateContainerMembership()
4d0c32f3
VK
1822{
1823 DWORD i;
1824 Container *pContainer;
1825
1826 if (g_pIndexById == NULL)
1827 return;
1828
1829 RWLockReadLock(g_rwlockIdIndex, INFINITE);
1830 for(i = 0; i < g_dwIdIndexSize; i++)
5039dede 1831 {
4d0c32f3
VK
1832 if ((((NetObj *)g_pIndexById[i].pObject)->Type() == OBJECT_CONTAINER) &&
1833 (!((NetObj *)g_pIndexById[i].pObject)->IsDeleted()))
1834 {
1835 pContainer = (Container *)g_pIndexById[i].pObject;
1836 if (pContainer->IsSuitableForNode(this))
1837 {
1838 if (!pContainer->IsChild(m_dwId))
1839 {
1840 DbgPrintf(4, _T("Node::UpdateContainerMembership(): binding node %d \"%s\" to container %d \"%s\""),
1841 m_dwId, m_szName, pContainer->Id(), pContainer->Name());
1842 pContainer->AddChild(this);
1843 AddParent(pContainer);
1844 }
1845 }
1846 else
1847 {
1848 if (pContainer->IsAutoBindEnabled() && pContainer->IsChild(m_dwId))
1849 {
1850 DbgPrintf(4, _T("Node::UpdateContainerMembership(): removing node %d \"%s\" from container %d \"%s\""),
1851 m_dwId, m_szName, pContainer->Id(), pContainer->Name());
1852 pContainer->DeleteChild(this);
1853 DeleteParent(pContainer);
1854 }
1855 }
1856 }
5039dede 1857 }
4d0c32f3 1858 RWLockUnlock(g_rwlockIdIndex);
5039dede
AK
1859}
1860
1861
1862//
1863// Connect to native agent
1864//
1865
a4569c4d 1866BOOL Node::connectToAgent(DWORD *error, DWORD *socketError)
5039dede
AK
1867{
1868 BOOL bRet;
1869
1870 // Create new agent connection object if needed
1871 if (m_pAgentConnection == NULL)
1872 m_pAgentConnection = new AgentConnectionEx(htonl(m_dwIpAddr), m_wAgentPort, m_wAuthMethod, m_szSharedSecret);
1873
1874 // Check if we already connected
45d84f8a 1875 if (m_pAgentConnection->nop() == ERR_SUCCESS)
5039dede
AK
1876 return TRUE;
1877
1878 // Close current connection or clean up after broken connection
7c521895
VK
1879 m_pAgentConnection->disconnect();
1880 m_pAgentConnection->setPort(m_wAgentPort);
1881 m_pAgentConnection->setAuthData(m_wAuthMethod, m_szSharedSecret);
1882 setAgentProxy(m_pAgentConnection);
a4569c4d 1883 bRet = m_pAgentConnection->connect(g_pServerKey, FALSE, error, socketError);
5039dede
AK
1884 if (bRet)
1885 {
45d84f8a
VK
1886 m_pAgentConnection->setCommandTimeout(g_dwAgentCommandTimeout);
1887 m_pAgentConnection->enableTraps();
5039dede
AK
1888 }
1889 return bRet;
1890}
1891
1892
1893//
1894// Get item's value via SNMP
1895//
1896
65e2005b 1897DWORD Node::GetItemFromSNMP(WORD port, const char *szParam, DWORD dwBufSize, char *szBuffer)
5039dede
AK
1898{
1899 DWORD dwResult;
1900
2fd7144f 1901 if ((((m_dwDynamicFlags & NDF_SNMP_UNREACHABLE) || !(m_dwFlags & NF_IS_SNMP)) && (port == 0)) ||
6b2bb22c
VK
1902 (m_dwDynamicFlags & NDF_UNREACHABLE) ||
1903 (m_dwFlags & NF_DISABLE_SNMP))
5039dede
AK
1904 {
1905 dwResult = SNMP_ERR_COMM;
1906 }
1907 else
1908 {
1909 SNMP_Transport *pTransport;
1910
65e2005b 1911 pTransport = createSnmpTransport(port);
803d47be
VK
1912 if (pTransport != NULL)
1913 {
1914 dwResult = SnmpGet(m_snmpVersion, pTransport,
1915 szParam, NULL, 0, szBuffer, dwBufSize, FALSE, TRUE);
1916 delete pTransport;
1917 }
1918 else
1919 {
1920 dwResult = SNMP_ERR_COMM;
1921 }
5039dede 1922 }
61b48d2f 1923 DbgPrintf(7, "Node(%s)->GetItemFromSNMP(%s): dwResult=%d", m_szName, szParam, dwResult);
5039dede
AK
1924 return (dwResult == SNMP_ERR_SUCCESS) ? DCE_SUCCESS :
1925 ((dwResult == SNMP_ERR_NO_OBJECT) ? DCE_NOT_SUPPORTED : DCE_COMM_ERROR);
1926}
1927
1928
1929//
1930// Get item's value via SNMP from CheckPoint's agent
1931//
1932
1933DWORD Node::GetItemFromCheckPointSNMP(const char *szParam, DWORD dwBufSize, char *szBuffer)
1934{
1935 DWORD dwResult;
1936
1937 if ((m_dwDynamicFlags & NDF_CPSNMP_UNREACHABLE) ||
1938 (m_dwDynamicFlags & NDF_UNREACHABLE))
1939 {
1940 dwResult = SNMP_ERR_COMM;
1941 }
1942 else
1943 {
1944 SNMP_Transport *pTransport;
1945
1946 pTransport = new SNMP_UDPTransport;
c4366266 1947 ((SNMP_UDPTransport *)pTransport)->createUDPTransport(NULL, htonl(m_dwIpAddr), CHECKPOINT_SNMP_PORT);
5039dede 1948 dwResult = SnmpGet(SNMP_VERSION_1, pTransport,
5d2c5741 1949 szParam, NULL, 0, szBuffer,
5039dede
AK
1950 dwBufSize, FALSE, TRUE);
1951 delete pTransport;
1952 }
61b48d2f 1953 DbgPrintf(7, "Node(%s)->GetItemFromCheckPointSNMP(%s): dwResult=%d", m_szName, szParam, dwResult);
5039dede
AK
1954 return (dwResult == SNMP_ERR_SUCCESS) ? DCE_SUCCESS :
1955 ((dwResult == SNMP_ERR_NO_OBJECT) ? DCE_NOT_SUPPORTED : DCE_COMM_ERROR);
1956}
1957
1958
1959//
1960// Get item's value via native agent
1961//
1962
1963DWORD Node::GetItemFromAgent(const char *szParam, DWORD dwBufSize, char *szBuffer)
1964{
912b994d 1965 DWORD dwError = ERR_NOT_CONNECTED, dwResult = DCE_COMM_ERROR;
5039dede
AK
1966 DWORD dwTries = 3;
1967
1968 if ((m_dwDynamicFlags & NDF_AGENT_UNREACHABLE) ||
2fd7144f
VK
1969 (m_dwDynamicFlags & NDF_UNREACHABLE) ||
1970 (m_dwFlags & NF_DISABLE_NXCP) ||
1971 !(m_dwFlags & NF_IS_NATIVE_AGENT))
5039dede
AK
1972 return DCE_COMM_ERROR;
1973
7c521895 1974 agentLock();
5039dede
AK
1975
1976 // Establish connection if needed
1977 if (m_pAgentConnection == NULL)
7c521895 1978 if (!connectToAgent())
5039dede
AK
1979 goto end_loop;
1980
1981 // Get parameter from agent
1982 while(dwTries-- > 0)
1983 {
1984 dwError = m_pAgentConnection->GetParameter((char *)szParam, dwBufSize, szBuffer);
1985 switch(dwError)
1986 {
1987 case ERR_SUCCESS:
1988 dwResult = DCE_SUCCESS;
1989 goto end_loop;
1990 case ERR_UNKNOWN_PARAMETER:
1991 dwResult = DCE_NOT_SUPPORTED;
1992 goto end_loop;
1993 case ERR_NOT_CONNECTED:
1994 case ERR_CONNECTION_BROKEN:
7c521895 1995 if (!connectToAgent())
5039dede
AK
1996 goto end_loop;
1997 break;
1998 case ERR_REQUEST_TIMEOUT:
1999 // Reset connection to agent after timeout
2000 DbgPrintf(7, _T("Node(%s)->GetItemFromAgent(%s): timeout; resetting connection to agent..."), m_szName, szParam);
2001 delete_and_null(m_pAgentConnection);
7c521895 2002 if (!connectToAgent())
5039dede
AK
2003 goto end_loop;
2004 DbgPrintf(7, _T("Node(%s)->GetItemFromAgent(%s): connection to agent restored successfully"), m_szName, szParam);
2005 break;
2006 }
2007 }
2008
2009end_loop:
7c521895 2010 agentUnlock();
5039dede
AK
2011 DbgPrintf(7, "Node(%s)->GetItemFromAgent(%s): dwError=%d dwResult=%d",
2012 m_szName, szParam, dwError, dwResult);
2013 return dwResult;
2014}
2015
2016
2017//
2018// Get value for server's internal parameter
2019//
2020
2021DWORD Node::GetInternalItem(const char *szParam, DWORD dwBufSize, char *szBuffer)
2022{
2023 DWORD dwError = DCE_SUCCESS;
2024
2025 if (!stricmp(szParam, "Status"))
2026 {
2027 sprintf(szBuffer, "%d", m_iStatus);
2028 }
2029 else if (!stricmp(szParam, "Dummy"))
2030 {
2031 _tcscpy(szBuffer, _T("0"));
2032 }
2033 else if (!stricmp(szParam, "AgentStatus"))
2034 {
2035 if (m_dwFlags & NF_IS_NATIVE_AGENT)
2036 {
2037 szBuffer[0] = (m_dwDynamicFlags & NDF_AGENT_UNREACHABLE) ? '1' : '0';
2038 szBuffer[1] = 0;
2039 }
2040 else
2041 {
2042 dwError = DCE_NOT_SUPPORTED;
2043 }
2044 }
2045 else if (MatchString("ChildStatus(*)", szParam, FALSE))
2046 {
2047 char *pEnd, szArg[256];
2048 DWORD i, dwId;
2049 NetObj *pObject = NULL;
2050
6173bea8 2051 AgentGetParameterArg((char *)szParam, 1, szArg, 256);
5039dede
AK
2052 dwId = strtoul(szArg, &pEnd, 0);
2053 if (*pEnd != 0)
2054 {
2055 // Argument is object's name
2056 dwId = 0;
2057 }
2058
2059 // Find child object with requested ID or name
2060 LockChildList(FALSE);
2061 for(i = 0; i < m_dwChildCount; i++)
2062 {
2063 if (((dwId == 0) && (!stricmp(m_pChildList[i]->Name(), szArg))) ||
2064 (dwId == m_pChildList[i]->Id()))
2065 {
2066 pObject = m_pChildList[i];
2067 break;
2068 }
2069 }
2070 UnlockChildList();
2071
2072 if (pObject != NULL)
2073 {
2074 sprintf(szBuffer, "%d", pObject->Status());
2075 }
2076 else
2077 {
2078 dwError = DCE_NOT_SUPPORTED;
2079 }
2080 }
2081 else if (MatchString("ConditionStatus(*)", szParam, FALSE))
2082 {
2083 char *pEnd, szArg[256];
2084 DWORD dwId;
2085 NetObj *pObject = NULL;
2086
6173bea8 2087 AgentGetParameterArg((char *)szParam, 1, szArg, 256);
5039dede
AK
2088 dwId = strtoul(szArg, &pEnd, 0);
2089 if (*pEnd == 0)
2090 {
2091 pObject = FindObjectById(dwId);
2092 if (pObject != NULL)
2093 if (pObject->Type() != OBJECT_CONDITION)
2094 pObject = NULL;
2095 }
2096 else
2097 {
2098 // Argument is object's name
2099 pObject = FindObjectByName(szArg, OBJECT_CONDITION);
2100 }
2101
2102 if (pObject != NULL)
2103 {
2104 if (pObject->IsTrustedNode(m_dwId))
2105 {
2106 sprintf(szBuffer, "%d", pObject->Status());
2107 }
2108 else
2109 {
2110 dwError = DCE_NOT_SUPPORTED;
2111 }
2112 }
2113 else
2114 {
2115 dwError = DCE_NOT_SUPPORTED;
2116 }
2117 }
2118 else if (m_dwFlags & NF_IS_LOCAL_MGMT)
2119 {
2120 if (!stricmp(szParam, "Server.AverageDCPollerQueueSize"))
2121 {
2122 sprintf(szBuffer, "%f", g_dAvgPollerQueueSize);
2123 }
2124 else if (!stricmp(szParam, "Server.AverageDBWriterQueueSize"))
2125 {
2126 sprintf(szBuffer, "%f", g_dAvgDBWriterQueueSize);
2127 }
2128 else if (!stricmp(szParam, "Server.AverageStatusPollerQueueSize"))
2129 {
2130 sprintf(szBuffer, "%f", g_dAvgStatusPollerQueueSize);
2131 }
2132 else if (!stricmp(szParam, "Server.AverageConfigurationPollerQueueSize"))
2133 {
2134 sprintf(szBuffer, "%f", g_dAvgConfigPollerQueueSize);
2135 }
2136 else if (!stricmp(szParam, "Server.AverageDCIQueuingTime"))
2137 {
2138 sprintf(szBuffer, "%u", g_dwAvgDCIQueuingTime);
2139 }
2140 else if (!stricmp(szParam, "Server.TotalEventsProcessed"))
2141 {
2142 sprintf(szBuffer, INT64_FMT, g_totalEventsProcessed);
2143 }
2144 else
2145 {
2146 dwError = DCE_NOT_SUPPORTED;
2147 }
2148 }
2149 else
2150 {
2151 dwError = DCE_NOT_SUPPORTED;
2152 }
2153
2154 return dwError;
2155}
2156
2157
2158//
2159// Get item's value for client
2160//
2161
2162DWORD Node::GetItemForClient(int iOrigin, const char *pszParam, char *pszBuffer, DWORD dwBufSize)
2163{
2164 DWORD dwResult = 0, dwRetCode;
2165
2166 // Get data from node
2167 switch(iOrigin)
2168 {
2169 case DS_INTERNAL:
2170 dwRetCode = GetInternalItem(pszParam, dwBufSize, pszBuffer);
2171 break;
2172 case DS_NATIVE_AGENT:
2173 dwRetCode = GetItemFromAgent(pszParam, dwBufSize, pszBuffer);
2174 break;
2175 case DS_SNMP_AGENT:
65e2005b 2176 dwRetCode = GetItemFromSNMP(0, pszParam, dwBufSize, pszBuffer);
5039dede
AK
2177 break;
2178 case DS_CHECKPOINT_AGENT:
2179 dwRetCode = GetItemFromCheckPointSNMP(pszParam, dwBufSize, pszBuffer);
2180 break;
2181 default:
2182 dwResult = RCC_INVALID_ARGUMENT;
2183 break;
2184 }
2185
2186 // Translate return code to RCC
2187 if (dwResult != RCC_INVALID_ARGUMENT)
2188 {
2189 switch(dwRetCode)
2190 {
2191 case DCE_SUCCESS:
2192 dwResult = RCC_SUCCESS;
2193 break;
2194 case DCE_COMM_ERROR:
2195 dwResult = RCC_COMM_FAILURE;
2196 break;
2197 case DCE_NOT_SUPPORTED:
2198 dwResult = RCC_DCI_NOT_SUPPORTED;
2199 break;
2200 default:
2201 dwResult = RCC_SYSTEM_FAILURE;
2202 break;
2203 }
2204 }
2205
2206 return dwResult;
2207}
2208
2209
2210//
2211// Put items which requires polling into the queue
2212//
2213
7c521895 2214void Node::queueItemsForPolling(Queue *pPollerQueue)
5039dede
AK
2215{
2216 DWORD i;
2217 time_t currTime;
2218
2219 if ((m_iStatus == STATUS_UNMANAGED) ||
2220 (m_dwFlags & NF_DISABLE_DATA_COLLECT) ||
2221 (m_bIsDeleted))
2222 return; // Do not collect data for unmanaged nodes or if data collection is disabled
2223
2224 currTime = time(NULL);
2225
7c521895 2226 lockDciAccess();
5039dede
AK
2227 for(i = 0; i < m_dwNumItems; i++)
2228 {
fb05c05b 2229 if (m_ppItems[i]->isReadyForPolling(currTime))
5039dede 2230 {
fb05c05b 2231 m_ppItems[i]->setBusyFlag(TRUE);
5039dede
AK
2232 IncRefCount(); // Increment reference count for each queued DCI
2233 pPollerQueue->Put(m_ppItems[i]);
61b48d2f 2234 DbgPrintf(8, _T("Node(%s)->QueueItemsForPolling(): item %d \"%s\" added to queue"), m_szName, m_ppItems[i]->getId(), m_ppItems[i]->getName());
5039dede
AK
2235 }
2236 }
7c521895 2237 unlockDciAccess();
5039dede
AK
2238}
2239
2240
2241//
2242// Create CSCP message with object's data
2243//
2244
2245void Node::CreateMessage(CSCPMessage *pMsg)
2246{
2247 Template::CreateMessage(pMsg);
2248 pMsg->SetVariable(VID_FLAGS, m_dwFlags);
fa6173b9 2249 pMsg->SetVariable(VID_RUNTIME_FLAGS, m_dwDynamicFlags);
5039dede
AK
2250 pMsg->SetVariable(VID_AGENT_PORT, m_wAgentPort);
2251 pMsg->SetVariable(VID_AUTH_METHOD, m_wAuthMethod);
2252 pMsg->SetVariable(VID_SHARED_SECRET, m_szSharedSecret);
4b7d8903
VK
2253 pMsg->SetVariable(VID_SNMP_AUTH_OBJECT, m_snmpSecurity->getCommunity());
2254 pMsg->SetVariable(VID_SNMP_AUTH_PASSWORD, m_snmpSecurity->getAuthPassword());
2255 pMsg->SetVariable(VID_SNMP_PRIV_PASSWORD, m_snmpSecurity->getPrivPassword());
2256 pMsg->SetVariable(VID_SNMP_USM_METHODS, (WORD)((WORD)m_snmpSecurity->getAuthMethod() | ((WORD)m_snmpSecurity->getPrivMethod() << 8)));
5039dede 2257 pMsg->SetVariable(VID_SNMP_OID, m_szObjectId);
65e2005b 2258 pMsg->SetVariable(VID_SNMP_PORT, m_wSNMPPort);
5039dede 2259 pMsg->SetVariable(VID_NODE_TYPE, m_dwNodeType);
5d2c5741 2260 pMsg->SetVariable(VID_SNMP_VERSION, (WORD)m_snmpVersion);
5039dede
AK
2261 pMsg->SetVariable(VID_AGENT_VERSION, m_szAgentVersion);
2262 pMsg->SetVariable(VID_PLATFORM_NAME, m_szPlatformName);
2263 pMsg->SetVariable(VID_POLLER_NODE_ID, m_dwPollerNode);
2264 pMsg->SetVariable(VID_ZONE_GUID, m_dwZoneGUID);
2265 pMsg->SetVariable(VID_PROXY_NODE, m_dwProxyNode);
2266 pMsg->SetVariable(VID_SNMP_PROXY, m_dwSNMPProxy);
2267 pMsg->SetVariable(VID_REQUIRED_POLLS, (WORD)m_iRequiredPollCount);
2268 pMsg->SetVariable(VID_SYS_DESCRIPTION, m_szSysDescription);
2269 pMsg->SetVariable(VID_USE_IFXTABLE, (WORD)m_nUseIfXTable);
2270}
2271
2272
2273//
2274// Modify object from message
2275//
2276
2277DWORD Node::ModifyFromMessage(CSCPMessage *pRequest, BOOL bAlreadyLocked)
2278{
5d2c5741
VK
2279 TCHAR buffer[256];
2280
5039dede
AK
2281 if (!bAlreadyLocked)
2282 LockData();
2283
2284 // Change primary IP address
2285 if (pRequest->IsVariableExist(VID_IP_ADDRESS))
2286 {
2287 DWORD i, dwIpAddr;
2288
2289 dwIpAddr = pRequest->GetVariableLong(VID_IP_ADDRESS);
2290
2291 // Check if received IP address is one of node's interface addresses
2292 LockChildList(FALSE);
2293 for(i = 0; i < m_dwChildCount; i++)
2294 if ((m_pChildList[i]->Type() == OBJECT_INTERFACE) &&
2295 (m_pChildList[i]->IpAddr() == dwIpAddr))
2296 break;
2297 UnlockChildList();
2298 if (i == m_dwChildCount)
2299 {
2300 UnlockData();
2301 return RCC_INVALID_IP_ADDR;
2302 }
2303
2304 UpdateNodeIndex(m_dwIpAddr, dwIpAddr, this);
2305 m_dwIpAddr = dwIpAddr;
2306 }
2307
2308 // Poller node ID
2309 if (pRequest->IsVariableExist(VID_POLLER_NODE_ID))
2310 {
2311 DWORD dwNodeId;
2312 NetObj *pObject;
2313
2314 dwNodeId = pRequest->GetVariableLong(VID_POLLER_NODE_ID);
2315 pObject = FindObjectById(dwNodeId);
2316
2317 // Check if received id is a valid node id
2318 if (pObject == NULL)
2319 {
2320 UnlockData();
2321 return RCC_INVALID_OBJECT_ID;
2322 }
2323 if (pObject->Type() != OBJECT_NODE)
2324 {
2325 UnlockData();
2326 return RCC_INVALID_OBJECT_ID;
2327 }
2328
2329 m_dwPollerNode = dwNodeId;
2330 }
2331
2332 // Change listen port of native agent
2333 if (pRequest->IsVariableExist(VID_AGENT_PORT))
2334 m_wAgentPort = pRequest->GetVariableShort(VID_AGENT_PORT);
2335
2336 // Change authentication method of native agent
2337 if (pRequest->IsVariableExist(VID_AUTH_METHOD))
2338 m_wAuthMethod = pRequest->GetVariableShort(VID_AUTH_METHOD);
2339
2340 // Change shared secret of native agent
2341 if (pRequest->IsVariableExist(VID_SHARED_SECRET))
2342 pRequest->GetVariableStr(VID_SHARED_SECRET, m_szSharedSecret, MAX_SECRET_LENGTH);
2343
2344 // Change SNMP protocol version
2345 if (pRequest->IsVariableExist(VID_SNMP_VERSION))
14b98b3a 2346 {
5d2c5741 2347 m_snmpVersion = pRequest->GetVariableShort(VID_SNMP_VERSION);
14b98b3a
VK
2348 m_snmpSecurity->setSecurityModel((m_snmpVersion == SNMP_VERSION_3) ? SNMP_SECURITY_MODEL_USM : SNMP_SECURITY_MODEL_V2C);
2349 }
5039dede 2350
65e2005b
VK
2351 // Change SNMP port
2352 if (pRequest->IsVariableExist(VID_SNMP_PORT))
2353 m_wSNMPPort = pRequest->GetVariableShort(VID_SNMP_PORT);
2354
4b7d8903
VK
2355 // Change SNMP authentication data
2356 if (pRequest->IsVariableExist(VID_SNMP_AUTH_OBJECT))
5d2c5741 2357 {
4b7d8903
VK
2358 pRequest->GetVariableStr(VID_SNMP_AUTH_OBJECT, buffer, 256);
2359 m_snmpSecurity->setAuthName(buffer);
2360
2361 pRequest->GetVariableStr(VID_SNMP_AUTH_PASSWORD, buffer, 256);
2362 m_snmpSecurity->setAuthPassword(buffer);
2363
2364 pRequest->GetVariableStr(VID_SNMP_PRIV_PASSWORD, buffer, 256);
2365 m_snmpSecurity->setPrivPassword(buffer);
2366
2367 WORD methods = pRequest->GetVariableShort(VID_SNMP_USM_METHODS);
2368 m_snmpSecurity->setAuthMethod((int)(methods & 0xFF));
2369 m_snmpSecurity->setPrivMethod((int)(methods >> 8));
5d2c5741 2370 }
5039dede
AK
2371
2372 // Change proxy node
2373 if (pRequest->IsVariableExist(VID_PROXY_NODE))
2374 m_dwProxyNode = pRequest->GetVariableLong(VID_PROXY_NODE);
2375
2376 // Change SNMP proxy node
2377 if (pRequest->IsVariableExist(VID_SNMP_PROXY))
2378 m_dwSNMPProxy = pRequest->GetVariableLong(VID_SNMP_PROXY);
2379
2380 // Number of required polls
2381 if (pRequest->IsVariableExist(VID_REQUIRED_POLLS))
2382 m_iRequiredPollCount = (int)pRequest->GetVariableShort(VID_REQUIRED_POLLS);
2383
2384 // Enable/disable usage of ifXTable
2385 if (pRequest->IsVariableExist(VID_USE_IFXTABLE))
2386 m_nUseIfXTable = (BYTE)pRequest->GetVariableShort(VID_USE_IFXTABLE);
2387
2388 // Change flags
2389 if (pRequest->IsVariableExist(VID_FLAGS))
2390 {
2391 m_dwFlags &= NF_SYSTEM_FLAGS;
2392 m_dwFlags |= pRequest->GetVariableLong(VID_FLAGS) & NF_USER_FLAGS;
2393 }
2394
2395 return Template::ModifyFromMessage(pRequest, TRUE);
2396}
2397
2398
2399//
2400// Wakeup node using magic packet
2401//
2402
7c521895 2403DWORD Node::wakeUp()
5039dede
AK
2404{
2405 DWORD i, dwResult = RCC_NO_WOL_INTERFACES;
2406
2407 LockChildList(FALSE);
2408
2409 for(i = 0; i < m_dwChildCount; i++)
2410 if ((m_pChildList[i]->Type() == OBJECT_INTERFACE) &&
2411 (m_pChildList[i]->Status() != STATUS_UNMANAGED) &&
2412 (m_pChildList[i]->IpAddr() != 0))
2413 {
7c521895 2414 dwResult = ((Interface *)m_pChildList[i])->wakeUp();
5039dede
AK
2415 break;
2416 }
2417
2418 UnlockChildList();
2419 return dwResult;
2420}
2421
2422
2423//
2424// Get status of interface with given index from SNMP agent
2425//
2426
58b3e451 2427int Node::getInterfaceStatusFromSNMP(SNMP_Transport *pTransport, DWORD dwIndex)
5039dede 2428{
5d2c5741 2429 return SnmpGetInterfaceStatus(m_snmpVersion, pTransport, dwIndex);
5039dede
AK
2430}
2431
2432
2433//
2434// Get status of interface with given index from native agent
2435//
2436
58b3e451 2437int Node::getInterfaceStatusFromAgent(DWORD dwIndex)
5039dede
AK
2438{
2439 char szParam[128], szBuffer[32];
2440 DWORD dwAdminStatus, dwLinkState;
2441 int iStatus;
2442
2443 // Get administrative status
2444 sprintf(szParam, "Net.Interface.AdminStatus(%u)", dwIndex);
2445 if (GetItemFromAgent(szParam, 32, szBuffer) == DCE_SUCCESS)
2446 {
2447 dwAdminStatus = strtoul(szBuffer, NULL, 0);
2448
2449 switch(dwAdminStatus)
2450 {
2451 case 3:
2452 iStatus = STATUS_TESTING;
2453 break;
2454 case 2:
2455 case 0: // Agents before 0.2.1 may return 0 instead of 2
2456 iStatus = STATUS_DISABLED;
2457 break;
2458 case 1: // Interface administratively up, check link state
2459 sprintf(szParam, "Net.Interface.Link(%u)", dwIndex);
2460 if (GetItemFromAgent(szParam, 32, szBuffer) == DCE_SUCCESS)
2461 {
2462 dwLinkState = strtoul(szBuffer, NULL, 0);
2463 iStatus = (dwLinkState == 0) ? STATUS_CRITICAL : STATUS_NORMAL;
2464 }
2465 else
2466 {
2467 iStatus = STATUS_UNKNOWN;
2468 }
2469 break;
2470 default:
2471 iStatus = STATUS_UNKNOWN;
2472 break;
2473 }
2474 }
2475 else
2476 {
2477 iStatus = STATUS_UNKNOWN;
2478 }
2479
2480 return iStatus;
2481}
2482
2483
2484//
2485// Put list of supported parameters into CSCP message
2486//
2487
2488void Node::WriteParamListToMessage(CSCPMessage *pMsg)
2489{
2490 DWORD i, dwId;
2491
2492 LockData();
2493 if (m_pParamList != NULL)
2494 {
2495 pMsg->SetVariable(VID_NUM_PARAMETERS, m_dwNumParams);
2496 for(i = 0, dwId = VID_PARAM_LIST_BASE; i < m_dwNumParams; i++)
2497 {
2498 pMsg->SetVariable(dwId++, m_pParamList[i].szName);
2499 pMsg->SetVariable(dwId++, m_pParamList[i].szDescription);
2500 pMsg->SetVariable(dwId++, (WORD)m_pParamList[i].iDataType);
2501 }
2502 DbgPrintf(6, _T("Node[%s]::WriteParamListToMessage(): sending %d parameters"), m_szName, m_dwNumParams);
2503 }
2504 else
2505 {
2506 DbgPrintf(6, _T("Node[%s]::WriteParamListToMessage(): m_pParamList == NULL"), m_szName);
2507 pMsg->SetVariable(VID_NUM_PARAMETERS, (DWORD)0);
2508 }
2509 UnlockData();
2510}
2511
2512
2513//
2514// Open list of supported parameters for reading
2515//
2516
2517void Node::OpenParamList(DWORD *pdwNumParams, NXC_AGENT_PARAM **ppParamList)
2518{
2519 LockData();
2520 *pdwNumParams = m_dwNumParams;
2521 *ppParamList = m_pParamList;
2522}
2523
2524
2525//
2526// Check status of network service
2527//
2528
2529DWORD Node::CheckNetworkService(DWORD *pdwStatus, DWORD dwIpAddr, int iServiceType,
2530 WORD wPort, WORD wProto, TCHAR *pszRequest,
2531 TCHAR *pszResponse)
2532{
2533 DWORD dwError = ERR_NOT_CONNECTED;
2534
2535 if ((m_dwFlags & NF_IS_NATIVE_AGENT) &&
2536 (!(m_dwDynamicFlags & NDF_AGENT_UNREACHABLE)) &&
2537 (!(m_dwDynamicFlags & NDF_UNREACHABLE)))
2538 {
2539 AgentConnection *pConn;
2540
cd9f247e 2541 pConn = createAgentConnection();
5039dede
AK
2542 if (pConn != NULL)
2543 {
2544 dwError = pConn->CheckNetworkService(pdwStatus, dwIpAddr, iServiceType,
2545 wPort, wProto, pszRequest, pszResponse);
7c521895 2546 pConn->disconnect();
5039dede
AK
2547 delete pConn;
2548 }
2549 }
2550 return dwError;
2551}
2552
2553
2554//
2555// Handler for object deletion
2556//
2557
2558void Node::OnObjectDelete(DWORD dwObjectId)
2559{
f5d16551 2560 LockData();
5039dede
AK
2561 if (dwObjectId == m_dwPollerNode)
2562 {
2563 // If deleted object is our poller node, change it to default
5039dede
AK
2564 m_dwPollerNode = 0;
2565 Modify();
2566 DbgPrintf(3, _T("Node \"%s\": poller node %d deleted"), m_szName, dwObjectId);
2567 }
f5d16551 2568 UnlockData();
5039dede
AK
2569}
2570
2571
2572//
2573// Check node for OSPF support
2574//
2575
2576void Node::CheckOSPFSupport(SNMP_Transport *pTransport)
2577{
2578 LONG nAdminStatus;
2579
5d2c5741 2580 if (SnmpGet(m_snmpVersion, pTransport,
5039dede
AK
2581 ".1.3.6.1.2.1.14.1.2.0", NULL, 0, &nAdminStatus, sizeof(LONG),
2582 FALSE, FALSE) == SNMP_ERR_SUCCESS)
2583 {
2584 LockData();
2585 if (nAdminStatus)
2586 {
2587 m_dwFlags |= NF_IS_OSPF;
2588 }
2589 else
2590 {
2591 m_dwFlags &= ~NF_IS_OSPF;
2592 }
2593 UnlockData();
2594 }
2595}
2596
2597
2598//
2599// Create ready to use agent connection
2600//
2601
cd9f247e 2602AgentConnectionEx *Node::createAgentConnection()
5039dede 2603{
45d84f8a 2604 AgentConnectionEx *conn;
5039dede
AK
2605
2606 if ((!(m_dwFlags & NF_IS_NATIVE_AGENT)) ||
6b2bb22c 2607 (m_dwFlags & NF_DISABLE_NXCP) ||
5039dede
AK
2608 (m_dwDynamicFlags & NDF_AGENT_UNREACHABLE) ||
2609 (m_dwDynamicFlags & NDF_UNREACHABLE))
2610 return NULL;
2611
45d84f8a
VK
2612 conn = new AgentConnectionEx(htonl(m_dwIpAddr), m_wAgentPort,
2613 m_wAuthMethod, m_szSharedSecret);
7c521895
VK
2614 setAgentProxy(conn);
2615 if (!conn->connect(g_pServerKey))
5039dede 2616 {
45d84f8a
VK
2617 delete conn;
2618 conn = NULL;
5039dede 2619 }
45d84f8a 2620 return conn;
5039dede
AK
2621}
2622
2623
2624//
2625// Get last collected values of all DCIs
2626//
2627
7c521895 2628DWORD Node::getLastValues(CSCPMessage *pMsg)
5039dede
AK
2629{
2630 DWORD i, dwId, dwCount;
2631
7c521895 2632 lockDciAccess();
5039dede
AK
2633
2634 for(i = 0, dwId = VID_DCI_VALUES_BASE, dwCount = 0; i < m_dwNumItems; i++)
2635 {
fb05c05b 2636 if (_tcsnicmp(m_ppItems[i]->getDescription(), _T("@system."), 8))
5039dede 2637 {
fb05c05b 2638 m_ppItems[i]->getLastValue(pMsg, dwId);
5039dede
AK
2639 dwId += 10;
2640 dwCount++;
2641 }
2642 }
2643 pMsg->SetVariable(VID_NUM_ITEMS, dwCount);
2644
7c521895 2645 unlockDciAccess();
5039dede
AK
2646 return RCC_SUCCESS;
2647}
2648
2649
2650//
2651// Clean expired DCI data
2652//
2653
7c521895 2654void Node::cleanDCIData()
5039dede
AK
2655{
2656 DWORD i;
2657
7c521895 2658 lockDciAccess();
5039dede 2659 for(i = 0; i < m_dwNumItems; i++)
fb05c05b 2660 m_ppItems[i]->deleteExpiredData();
7c521895 2661 unlockDciAccess();
5039dede
AK
2662}
2663
2664
2665//
2666// Apply DCI from template
2667// pItem passed to this method should be a template's DCI
2668//
2669
a2069340 2670BOOL Node::applyTemplateItem(DWORD dwTemplateId, DCItem *pItem)
5039dede
AK
2671{
2672 BOOL bResult = TRUE;
2673 DWORD i;
2674 DCItem *pNewItem;
2675
a2069340 2676 lockDciAccess(); // write lock
5039dede 2677
fb05c05b 2678 DbgPrintf(5, "Applying item \"%s\" to node \"%s\"", pItem->getName(), m_szName);
5039dede
AK
2679
2680 // Check if that template item exists
2681 for(i = 0; i < m_dwNumItems; i++)
fb05c05b
VK
2682 if ((m_ppItems[i]->getTemplateId() == dwTemplateId) &&
2683 (m_ppItems[i]->getTemplateItemId() == pItem->getId()))
5039dede
AK
2684 break; // Item with specified id already exist
2685
2686 if (i == m_dwNumItems)
2687 {
2688 // New item from template, just add it
2689 pNewItem = new DCItem(pItem);
fb05c05b
VK
2690 pNewItem->setTemplateId(dwTemplateId, pItem->getId());
2691 pNewItem->changeBinding(CreateUniqueId(IDG_ITEM), this, TRUE);
7c521895 2692 bResult = addItem(pNewItem, true);
5039dede
AK
2693 }
2694 else
2695 {
2696 // Update existing item
fb05c05b 2697 m_ppItems[i]->updateFromTemplate(pItem);
5039dede
AK
2698 }
2699
7c521895
VK
2700 unlockDciAccess();
2701
2702 if (bResult)
2703 {
2704 LockData();
2705 m_bIsModified = TRUE;
2706 UnlockData();
2707 }
5039dede
AK
2708 return bResult;
2709}
2710
2711
2712//
2713// Clean deleted template items from node's DCI list
2714// Arguments is template id and list of valid template item ids.
2715// all items related to given template and not presented in list should be deleted.
2716//
2717
a2069340 2718void Node::cleanDeletedTemplateItems(DWORD dwTemplateId, DWORD dwNumItems, DWORD *pdwItemList)
5039dede
AK
2719{
2720 DWORD i, j, dwNumDeleted, *pdwDeleteList;
2721
a2069340 2722 lockDciAccess(); // write lock
5039dede
AK
2723
2724 pdwDeleteList = (DWORD *)malloc(sizeof(DWORD) * m_dwNumItems);
2725 dwNumDeleted = 0;
2726
2727 for(i = 0; i < m_dwNumItems; i++)
fb05c05b 2728 if (m_ppItems[i]->getTemplateId() == dwTemplateId)
5039dede
AK
2729 {
2730 for(j = 0; j < dwNumItems; j++)
fb05c05b 2731 if (m_ppItems[i]->getTemplateItemId() == pdwItemList[j])
5039dede
AK
2732 break;
2733
2734 // Delete DCI if it's not in list
2735 if (j == dwNumItems)
fb05c05b 2736 pdwDeleteList[dwNumDeleted++] = m_ppItems[i]->getId();
5039dede
AK
2737 }
2738
2739 for(i = 0; i < dwNumDeleted; i++)
7c521895 2740 deleteItem(pdwDeleteList[i], false);
5039dede 2741
7c521895 2742 unlockDciAccess();
5039dede
AK
2743 free(pdwDeleteList);
2744}
2745
2746
2747//
2748// Unbind node from template, i.e either remove DCI association with template
2749// or remove these DCIs at all
2750//
2751
a2069340 2752void Node::unbindFromTemplate(DWORD dwTemplateId, BOOL bRemoveDCI)
5039dede 2753{
17b055bb 2754 DWORD i;
5039dede
AK
2755
2756 if (bRemoveDCI)
2757 {
17b055bb
VK
2758 DWORD *pdwDeleteList = (DWORD *)malloc(sizeof(DWORD) * m_dwNumItems);
2759 DWORD dwNumDeleted = 0;
5039dede 2760
a2069340 2761 lockDciAccess(); // write lock
5039dede
AK
2762
2763 for(i = 0; i < m_dwNumItems; i++)
fb05c05b 2764 if (m_ppItems[i]->getTemplateId() == dwTemplateId)
5039dede 2765 {
fb05c05b 2766 pdwDeleteList[dwNumDeleted++] = m_ppItems[i]->getId();
5039dede
AK
2767 }
2768
2769 for(i = 0; i < dwNumDeleted; i++)
7c521895 2770 deleteItem(pdwDeleteList[i], false);
5039dede 2771
7c521895 2772 unlockDciAccess();
17b055bb
VK
2773
2774 safe_free(pdwDeleteList);
5039dede
AK
2775 }
2776 else
2777 {
7c521895 2778 lockDciAccess();
5039dede
AK
2779
2780 for(i = 0; i < m_dwNumItems; i++)
fb05c05b 2781 if (m_ppItems[i]->getTemplateId() == dwTemplateId)
5039dede 2782 {
fb05c05b 2783 m_ppItems[i]->setTemplateId(0, 0);
5039dede
AK
2784 }
2785
7c521895 2786 unlockDciAccess();
5039dede
AK
2787 }
2788}
2789
2790
2791//
2792// Change node's IP address
2793//
2794
58b3e451 2795void Node::changeIPAddress(DWORD dwIpAddr)
5039dede
AK
2796{
2797 DWORD i;
2798
7c521895 2799 pollerLock();
5039dede
AK
2800
2801 LockData();
2802
2803 UpdateNodeIndex(m_dwIpAddr, dwIpAddr, this);
2804 m_dwIpAddr = dwIpAddr;
2805 m_dwDynamicFlags |= NDF_FORCE_CONFIGURATION_POLL | NDF_RECHECK_CAPABILITIES;
2806
2807 // Change status of node and all it's childs to UNKNOWN
2808 m_iStatus = STATUS_UNKNOWN;
2809 LockChildList(FALSE);
2810 for(i = 0; i < m_dwChildCount; i++)
2811 {
2812 m_pChildList[i]->ResetStatus();
2813 if (m_pChildList[i]->Type() == OBJECT_INTERFACE)
2814 {
2815 if (((Interface *)m_pChildList[i])->IsFake())
2816 {
2817 ((Interface *)m_pChildList[i])->SetIpAddr(dwIpAddr);
2818 }
2819 }
2820 }
2821 UnlockChildList();
2822
2823 Modify();
2824 UnlockData();
2825
7c521895 2826 agentLock();
5039dede 2827 delete_and_null(m_pAgentConnection);
7c521895 2828 agentUnlock();
5039dede 2829
7c521895 2830 pollerUnlock();
5039dede
AK
2831}
2832
2833
2834//
2835// Get number of interface objects and pointer to the last one
2836//
2837
7c521895 2838DWORD Node::getInterfaceCount(Interface **ppInterface)
5039dede
AK
2839{
2840 DWORD i, dwCount;
2841
2842 LockChildList(FALSE);
2843 for(i = 0, dwCount = 0; i < m_dwChildCount; i++)
2844 if (m_pChildList[i]->Type() == OBJECT_INTERFACE)
2845 {
2846 dwCount++;
2847 *ppInterface = (Interface *)m_pChildList[i];
2848 }
2849 UnlockChildList();
2850 return dwCount;
2851}
2852
2853
2854//
2855// Update cache for all DCI's
2856//
2857
a2069340 2858void Node::updateDciCache()
5039dede
AK
2859{
2860 DWORD i;
2861
a2069340 2862 lockDciAccess();
5039dede 2863 for(i = 0; i < m_dwNumItems; i++)
fb05c05b 2864 m_ppItems[i]->updateCacheSize();
a2069340 2865 unlockDciAccess();
5039dede
AK
2866}
2867
2868
2869//
2870// Get routing table from node
2871//
2872
58b3e451 2873ROUTING_TABLE *Node::getRoutingTable()
5039dede
AK
2874{
2875 ROUTING_TABLE *pRT = NULL;
2876
2877 if ((m_dwFlags & NF_IS_NATIVE_AGENT) && (!(m_dwFlags & NF_DISABLE_NXCP)))
2878 {
7c521895
VK
2879 agentLock();
2880 if (connectToAgent())
5039dede
AK
2881 {
2882 pRT = m_pAgentConnection->GetRoutingTable();
2883 }
7c521895 2884 agentUnlock();
5039dede
AK
2885 }
2886 if ((pRT == NULL) && (m_dwFlags & NF_IS_SNMP) && (!(m_dwFlags & NF_DISABLE_SNMP)))
2887 {
2888 SNMP_Transport *pTransport;
2889
cd9f247e 2890 pTransport = createSnmpTransport();
803d47be
VK
2891 if (pTransport != NULL)
2892 {
2893 pRT = SnmpGetRoutingTable(m_snmpVersion, pTransport);
2894 delete pTransport;
2895 }
5039dede
AK
2896 }
2897
2898 if (pRT != NULL)
2899 {
2900 SortRoutingTable(pRT);
2901 }
2902 return pRT;
2903}
2904
2905
2906//
2907// Get next hop for given destination address
2908//
2909
58b3e451 2910BOOL Node::getNextHop(DWORD dwSrcAddr, DWORD dwDestAddr, DWORD *pdwNextHop,
5039dede
AK
2911 DWORD *pdwIfIndex, BOOL *pbIsVPN)
2912{
2913 DWORD i;
2914 BOOL bResult = FALSE;
2915
2916 // Check VPN connectors
2917 LockChildList(FALSE);
2918 for(i = 0; i < m_dwChildCount; i++)
2919 if (m_pChildList[i]->Type() == OBJECT_VPNCONNECTOR)
2920 {
2921 if (((VPNConnector *)m_pChildList[i])->IsRemoteAddr(dwDestAddr) &&
2922 ((VPNConnector *)m_pChildList[i])->IsLocalAddr(dwSrcAddr))
2923 {
2924 *pdwNextHop = ((VPNConnector *)m_pChildList[i])->GetPeerGatewayAddr();
2925 *pdwIfIndex = m_pChildList[i]->Id();
2926 *pbIsVPN = TRUE;
2927 bResult = TRUE;
2928 break;
2929 }
2930 }
2931 UnlockChildList();
2932
2933 // Check routing table
2934 if (!bResult)
2935 {
7c521895 2936 routingTableLock();
5039dede
AK
2937 if (m_pRoutingTable != NULL)
2938 {
2939 for(i = 0; i < (DWORD)m_pRoutingTable->iNumEntries; i++)
2940 if ((dwDestAddr & m_pRoutingTable->pRoutes[i].dwDestMask) == m_pRoutingTable->pRoutes[i].dwDestAddr)
2941 {
2942 *pdwNextHop = m_pRoutingTable->pRoutes[i].dwNextHop;
2943 *pdwIfIndex = m_pRoutingTable->pRoutes[i].dwIfIndex;
2944 *pbIsVPN = FALSE;
2945 bResult = TRUE;
2946 break;
2947 }
2948 }
7c521895 2949 routingTableUnlock();
5039dede
AK
2950 }
2951
2952 return bResult;
2953}
2954
2955
2956//
2957// Update cached routing table
2958//
2959
58b3e451 2960void Node::updateRoutingTable()
5039dede
AK
2961{
2962 ROUTING_TABLE *pRT;
2963
58b3e451 2964 pRT = getRoutingTable();
5039dede
AK
2965 if (pRT != NULL)
2966 {
7c521895 2967 routingTableLock();
5039dede
AK
2968 DestroyRoutingTable(m_pRoutingTable);
2969 m_pRoutingTable = pRT;
7c521895 2970 routingTableUnlock();
5039dede
AK
2971 }
2972 m_tLastRTUpdate = time(NULL);
2973 m_dwDynamicFlags &= ~NDF_QUEUED_FOR_ROUTE_POLL;
2974}
2975
2976
2977//
2978// Call SNMP Enumerate with node's SNMP parameters
2979//
2980
2981DWORD Node::CallSnmpEnumerate(const char *pszRootOid,
5d2c5741 2982 DWORD (* pHandler)(DWORD, SNMP_Variable *, SNMP_Transport *, void *),
5039dede
AK
2983 void *pArg)
2984{
2985 if ((m_dwFlags & NF_IS_SNMP) &&
2986 (!(m_dwDynamicFlags & NDF_SNMP_UNREACHABLE)) &&
2987 (!(m_dwDynamicFlags & NDF_UNREACHABLE)))
2988 {
2989 SNMP_Transport *pTransport;
2990 DWORD dwResult;
2991
cd9f247e 2992 pTransport = createSnmpTransport();
803d47be
VK
2993 if (pTransport != NULL)
2994 {
2995 dwResult = SnmpEnumerate(m_snmpVersion, pTransport,
2996 pszRootOid, pHandler, pArg, FALSE);
2997 delete pTransport;
2998 }
2999 else
3000 {
3001 dwResult = SNMP_ERR_COMM;
3002 }
5039dede
AK
3003 return dwResult;
3004 }
3005 else
3006 {
3007 return SNMP_ERR_COMM;
3008 }
3009}
3010
3011
3012//
3013// Set proxy information for agent's connection
3014//
3015
7c521895 3016void Node::setAgentProxy(AgentConnection *pConn)
5039dede
AK
3017{
3018 if (m_dwProxyNode != 0)
3019 {
3020 Node *pNode;
3021
3022 pNode = (Node *)FindObjectById(m_dwProxyNode);
3023 if (pNode != NULL)
3024 {
7c521895 3025 pConn->setProxy(htonl(pNode->m_dwIpAddr), pNode->m_wAgentPort,
5039dede
AK
3026 pNode->m_wAuthMethod, pNode->m_szSharedSecret);
3027 }
3028 }
3029}
3030
3031
3032//
3033// Prepare node object for deletion
3034//
3035
3036void Node::PrepareForDeletion(void)
3037{
3038 // Prevent node from being queued for polling
3039 LockData();
3040 m_dwDynamicFlags |= NDF_POLLING_DISABLED;
3041 UnlockData();
3042
3043 // Wait for all pending polls
3044 while(1)
3045 {
3046 LockData();
3047 if ((m_dwDynamicFlags &
3048 (NDF_QUEUED_FOR_STATUS_POLL | NDF_QUEUED_FOR_CONFIG_POLL |
3049 NDF_QUEUED_FOR_DISCOVERY_POLL | NDF_QUEUED_FOR_ROUTE_POLL)) == 0)
3050 {
3051 UnlockData();
3052 break;
3053 }
3054 UnlockData();
3055 ThreadSleepMs(100);
3056 }
3057 Template::PrepareForDeletion();
3058}
3059
3060
3061//
3062// Check if specified SNMP variable set to specified value.
3063// If variable doesn't exist at all, will return FALSE
3064//
3065
3066BOOL Node::CheckSNMPIntegerValue(SNMP_Transport *pTransport, const char *pszOID, int nValue)
3067{
3068 DWORD dwTemp;
3069
5d2c5741
VK
3070 if (SnmpGet(m_snmpVersion, pTransport, pszOID, NULL, 0, &dwTemp,
3071 sizeof(DWORD), FALSE, FALSE) == SNMP_ERR_SUCCESS)
5039dede
AK
3072 return (int)dwTemp == nValue;
3073 return FALSE;
3074}
3075
3076
3077//
3078// Check and update if needed interface names
3079//
3080
3081void Node::CheckInterfaceNames(INTERFACE_LIST *pIfList)
3082{
3083 int i;
3084 TCHAR *ptr;
3085
3086 if ((m_dwNodeType == NODE_TYPE_NORTEL_BAYSTACK) ||
3087 (m_dwNodeType == NODE_TYPE_NORTEL_OPTERA))
3088 {
3089 // Translate interface names
3090 for(i = 0; i < pIfList->iNumEntries; i++)
3091 {
3092 if ((ptr = _tcsstr(pIfList->pInterfaces[i].szName, _T("- Port"))) != NULL)
3093 {
3094 ptr += 2;
3095 memmove(pIfList->pInterfaces[i].szName, ptr, _tcslen(ptr) + 1);
3096 }
3097 else if ((ptr = _tcsstr(pIfList->pInterfaces[i].szName, _T("- Unit"))) != NULL)
3098 {
3099 ptr += 2;
3100 memmove(pIfList->pInterfaces[i].szName, ptr, _tcslen(ptr) + 1);
3101 }
3102 else if ((_tcsstr(pIfList->pInterfaces[i].szName, _T("BayStack")) != NULL) ||
3103 (_tcsstr(pIfList->pInterfaces[i].szName, _T("Nortel Ethernet Switch")) != NULL))
3104 {
3105 ptr = _tcsrchr(pIfList->pInterfaces[i].szName, _T('-'));
3106 if (ptr != NULL)
3107 {
3108 ptr++;
3109 while(*ptr == _T(' '))
3110 ptr++;
3111 memmove(pIfList->pInterfaces[i].szName, ptr, _tcslen(ptr) + 1);
3112 }
3113 }
3114 StrStrip(pIfList->pInterfaces[i].szName);
3115 }
3116 }
3117
3118 // Cut interface names to MAX_OBJECT_NAME and check for unnamed interfaces
3119 for(i = 0; i < pIfList->iNumEntries; i++)
3120 {
3121 pIfList->pInterfaces[i].szName[MAX_OBJECT_NAME - 1] = 0;
3122 if (pIfList->pInterfaces[i].szName[0] == 0)
3123 _stprintf(pIfList->pInterfaces[i].szName, _T("%d"), pIfList->pInterfaces[i].dwIndex);
3124 }
3125}
3126
3127
3128//
3129// Get cluster object this node belongs to, if any
3130//
3131
7c521895 3132Cluster *Node::getMyCluster()
5039dede
AK
3133{
3134 DWORD i;
3135 Cluster *pCluster = NULL;
3136
3137 LockParentList(FALSE);
3138 for(i = 0; i < m_dwParentCount; i++)
3139 if (m_pParentList[i]->Type() == OBJECT_CLUSTER)
3140 {
3141 pCluster = (Cluster *)m_pParentList[i];
3142 break;
3143 }
3144 UnlockParentList();
3145 return pCluster;
3146}
3147
3148
3149//
3150// Create SNMP transport
3151//
3152
65e2005b 3153SNMP_Transport *Node::createSnmpTransport(WORD port)
5039dede
AK
3154{
3155 SNMP_Transport *pTransport = NULL;
3156
3157 if (m_dwSNMPProxy == 0)
3158 {
3159 pTransport = new SNMP_UDPTransport;
65e2005b 3160 ((SNMP_UDPTransport *)pTransport)->createUDPTransport(NULL, htonl(m_dwIpAddr), (port != 0) ? port : m_wSNMPPort);
5039dede
AK
3161 }
3162 else
3163 {
3164 NetObj *pObject;
3165
3166 pObject = FindObjectById(m_dwSNMPProxy);
3167 if (pObject != NULL)
3168 {
3169 if (pObject->Type() == OBJECT_NODE)
3170 {
3171 AgentConnection *pConn;
3172
cd9f247e 3173 pConn = ((Node *)pObject)->createAgentConnection();
5039dede
AK
3174 if (pConn != NULL)
3175 {
65e2005b 3176 pTransport = new SNMP_ProxyTransport(pConn, m_dwIpAddr, (port != 0) ? port : m_wSNMPPort);
5039dede
AK
3177 }
3178 }
3179 }
3180 }
5d2c5741
VK
3181
3182 // Set security
3183 if (pTransport != NULL)
3184 {
df8a4ca2 3185 LockData();
5d2c5741 3186 pTransport->setSecurityContext(new SNMP_SecurityContext(m_snmpSecurity));
df8a4ca2 3187 UnlockData();
5d2c5741 3188 }
5039dede
AK
3189 return pTransport;
3190}
cd9f247e
VK
3191
3192
3193//
3194// Get SNMP security context
3195// ATTENTION: This method returns new copy of security context
3196// which must be destroyed by the caller
3197//
3198
3199SNMP_SecurityContext *Node::getSnmpSecurityContext()
3200{
3201 LockData();
3202 SNMP_SecurityContext *ctx = new SNMP_SecurityContext(m_snmpSecurity);
3203 UnlockData();
3204 return ctx;
3205}
5039dede
AK
3206
3207
3208//
3209// Resolve node's name
3210//
3211
3212BOOL Node::ResolveName(BOOL useOnlyDNS)
3213{
3214 BOOL bSuccess = FALSE;
3215 HOSTENT *hs;
3216 DWORD i, dwAddr;
3217 TCHAR szBuffer[256];
3218
3219 DbgPrintf(4, _T("Resolving name for node %d [%s]..."), m_dwId, m_szName);
3220
3221 // Try to resolve primary IP
3222 dwAddr = htonl(m_dwIpAddr);
3223 hs = gethostbyaddr((const char *)&dwAddr, 4, AF_INET);
3224 if (hs != NULL)
3225 {
3226 nx_strncpy(m_szName, hs->h_name, MAX_OBJECT_NAME);
3227 bSuccess = TRUE;
3228 }
3229 else
3230 {
3231 // Try to resolve each interface's IP address
3232 LockChildList(FALSE);
3233 for(i = 0; i < m_dwChildCount; i++)
3234 {
3235 if (m_pChildList[i]->Type() == OBJECT_INTERFACE)
3236 {
3237 dwAddr = htonl(m_pChildList[i]->IpAddr());
3238 if (dwAddr != 0)
3239 {
3240 hs = gethostbyaddr((const char *)&dwAddr, 4, AF_INET);
3241 if (hs != NULL)
3242 {
3243 nx_strncpy(m_szName, hs->h_name, MAX_OBJECT_NAME);
3244 bSuccess = TRUE;
3245 break;
3246 }
3247 }
3248 }
3249 }
3250 UnlockChildList();
3251
3252 // Try to get hostname from agent if address resolution fails
3253 if (!(bSuccess || useOnlyDNS))
3254 {
3255 DbgPrintf(4, _T("Resolving name for node %d [%s] via agent..."), m_dwId, m_szName);
3256 if (GetItemFromAgent("System.Hostname", 256, szBuffer) == DCE_SUCCESS)
3257 {
3258 StrStrip(szBuffer);
3259 if (szBuffer[0] != 0)
3260 {
3261 nx_strncpy(m_szName, szBuffer, MAX_OBJECT_NAME);
3262 bSuccess = TRUE;
3263 }
3264 }
3265 }
3266
3267 // Try to get hostname from SNMP if other methods fails
3268 if (!(bSuccess || useOnlyDNS))
3269 {
3270 DbgPrintf(4, _T("Resolving name for node %d [%s] via SNMP..."), m_dwId, m_szName);
65e2005b 3271 if (GetItemFromSNMP(0, ".1.3.6.1.2.1.1.5.0", 256, szBuffer) == DCE_SUCCESS)
5039dede
AK
3272 {
3273 StrStrip(szBuffer);
3274 if (szBuffer[0] != 0)
3275 {
3276 nx_strncpy(m_szName, szBuffer, MAX_OBJECT_NAME);
3277 bSuccess = TRUE;
3278 }
3279 }
3280 }
3281 }
3282
3283 if (bSuccess)
3284 DbgPrintf(4, _T("Name for node %d was resolved to %s"), m_dwId, m_szName);
3285 else
3286 DbgPrintf(4, _T("Name for node %d was not resolved"), m_dwId, m_szName);
3287 return bSuccess;
3288}
3289
3290
3291//
3292// Send list of system DCIs
3293//
3294
74526d25 3295DWORD Node::getPerfTabDCIList(CSCPMessage *pMsg)
5039dede
AK
3296{
3297 DWORD i, dwId, dwCount;
3298
3299 LockData();
3300
3301 for(i = 0, dwId = VID_SYSDCI_LIST_BASE, dwCount = 0; i < m_dwNumItems; i++)
3302 {
74526d25
VK
3303 if (!_tcsnicmp(m_ppItems[i]->getDescription(), _T("@System."), 8) ||
3304 (m_ppItems[i]->getPerfTabSettings() != NULL))
5039dede 3305 {
fb05c05b
VK
3306 pMsg->SetVariable(dwId++, m_ppItems[i]->getId());
3307 pMsg->SetVariable(dwId++, (TCHAR *)m_ppItems[i]->getDescription());
3308 pMsg->SetVariable(dwId++, (WORD)m_ppItems[i]->getStatus());
e76d8b6f
VK
3309 if (m_ppItems[i]->getPerfTabSettings() != NULL)
3310 {
3311 pMsg->SetVariable(dwId++, m_ppItems[i]->getPerfTabSettings());
3312 dwId += 6;
3313 }
3314 else
3315 {
3316 dwId += 7;
3317 }
5039dede
AK
3318 dwCount++;
3319 }
3320 }
3321 pMsg->SetVariable(VID_NUM_ITEMS, dwCount);
3322
3323 UnlockData();
3324 return RCC_SUCCESS;
3325}
3326
3327
3328//
3329// Get current layer 2 topology (as dynamically created list which should be destroyed by caller)
3330// Will return NULL if there are no topology information or it is expired
3331//
3332
3333nxmap_ObjList *Node::GetL2Topology(void)
3334{
3335 nxmap_ObjList *pResult;
3336 DWORD dwExpTime;
3337
3338 dwExpTime = ConfigReadULong(_T("TopologyExpirationTime"), 900);
3339 MutexLock(m_mutexTopoAccess, INFINITE);
3340 if ((m_pTopology == NULL) || (m_tLastTopologyPoll + (time_t)dwExpTime < time(NULL)))
3341 {
3342 pResult = NULL;
3343 }
3344 else
3345 {
3346 pResult = new nxmap_ObjList(m_pTopology);
3347 }
3348 MutexUnlock(m_mutexTopoAccess);
3349 return pResult;
3350}
3351
3352
3353//
3354// Rebuild layer 2 topology and return it as dynamically reated list which should be destroyed by caller
3355//
3356
3357nxmap_ObjList *Node::BuildL2Topology(DWORD *pdwStatus)
3358{
3359 nxmap_ObjList *pResult;
3360 int nDepth;
3361
3362 nDepth = ConfigReadInt(_T("TopologyDiscoveryRadius"), 5);
3363 MutexLock(m_mutexTopoAccess, INFINITE);
3364 delete m_pTopology;
3365 if ((m_dwFlags & NF_IS_CDP) || (m_dwFlags & NF_IS_SONMP) || (m_dwFlags & NF_IS_LLDP))
3366 {
3367 m_pTopology = new nxmap_ObjList;
3368 if ((*pdwStatus = ::BuildL2Topology(*m_pTopology, this, NULL, nDepth, NULL)) == RCC_SUCCESS)
3369 {
3370 m_tLastTopologyPoll = time(NULL);
3371 pResult = new nxmap_ObjList(m_pTopology);
3372 }
3373 else
3374 {
3375 delete_and_null(m_pTopology);
3376 pResult = NULL;
3377 }
3378 }
3379 else
3380 {
3381 pResult = NULL;
3382 m_pTopology = NULL;
3383 *pdwStatus = RCC_NO_L2_TOPOLOGY_SUPPORT;
3384 }
3385 MutexUnlock(m_mutexTopoAccess);
3386 return pResult;
3387}
3388
3389
3390//
3391// Check subnet bindings
3392//
3393
3394void Node::CheckSubnetBinding(INTERFACE_LIST *pIfList)
3395{
3396 Subnet *pSubnet;
3397 Interface *pInterface;
3398 Cluster *pCluster;
3399 NetObj **ppUnlinkList;
3400 int i, j, count;
3401 BOOL isSync;
3402
7c521895 3403 pCluster = getMyCluster();
5039dede
AK
3404
3405 // Check if we have subnet bindings for all interfaces
3406 for(i = 0; i < pIfList->iNumEntries; i++)
3407 {
3408 if (pIfList->pInterfaces[i].dwIpAddr != 0)
3409 {
58b3e451 3410 pInterface = findInterface(pIfList->pInterfaces[i].dwIndex, pIfList->pInterfaces[i].dwIpAddr);
5039dede
AK
3411 if (pInterface == NULL)
3412 {
3413 nxlog_write(MSG_INTERNAL_ERROR, EVENTLOG_WARNING_TYPE, "s", _T("Cannot find interface object in Node::CheckSubnetBinding()"));
3414 break; // Something goes really wrong
3415 }
3416
3417 // Is cluster interconnect interface?
58b3e451 3418 isSync = (pCluster != NULL) ? pCluster->isSyncAddr(pInterface->IpAddr()) : FALSE;
5039dede
AK
3419
3420 pSubnet = FindSubnetForNode(pIfList->pInterfaces[i].dwIpAddr);
3421 if (pSubnet != NULL)
3422 {
3423 if (isSync)
3424 {
3425 pSubnet = NULL; // No further checks on this subnet
3426 }
3427 else
3428 {
3429 if (pSubnet->IsSyntheticMask())
3430 {
3431 DbgPrintf(4, _T("Setting correct netmask for subnet %s [%d] from node %s [%d]"),
3432 pSubnet->Name(), pSubnet->Id(), m_szName, m_dwId);
3433 pSubnet->SetCorrectMask(pInterface->IpAddr() & pInterface->IpNetMask(), pInterface->IpNetMask());
3434 }
3435 }
3436 }
3437 else if (!isSync)
3438 {
3439 // Create subnet
3440 pSubnet = new Subnet(pIfList->pInterfaces[i].dwIpAddr & pIfList->pInterfaces[i].dwIpNetMask,
3441 pIfList->pInterfaces[i].dwIpNetMask, m_dwZoneGUID, FALSE);
3442 NetObjInsert(pSubnet, TRUE);
3443 g_pEntireNet->AddSubnet(pSubnet);
3444 pSubnet->AddNode(this);
3445 DbgPrintf(4, _T("Node::CheckSubnetBinding(): Creating new subnet %s [%d] for node %s [%d]"),
3446 pSubnet->Name(), pSubnet->Id(), m_szName, m_dwId);
3447 }
3448
3449 // Check if subnet mask is correct on interface
3450 if ((pSubnet != NULL) && (pSubnet->IpNetMask() != pIfList->pInterfaces[i].dwIpNetMask))
3451 {
3452 PostEvent(EVENT_INCORRECT_NETMASK, m_dwId, "idsaa", pInterface->Id(),
3453 pInterface->IfIndex(), pInterface->Name(),
3454 pInterface->IpNetMask(), pSubnet->IpNetMask());
3455 }
3456 }
3457 }
3458
3459 // Check if we have incorrect subnets as parents
3460 LockParentList(FALSE);
3461 LockChildList(FALSE);
3462 ppUnlinkList = (NetObj **)malloc(sizeof(NetObj *) * m_dwParentCount);
3463 for(i = 0, count = 0; i < (int)m_dwParentCount; i++)
3464 {
3465 if (m_pParentList[i]->Type() == OBJECT_SUBNET)
3466 {
3467 pSubnet = (Subnet *)m_pParentList[i];
3468 for(j = 0; j < (int)m_dwChildCount; j++)
3469 {
3470 if (m_pChildList[j]->Type() == OBJECT_INTERFACE)
3471 {
3472 if (pSubnet->IpAddr() == (m_pChildList[j]->IpAddr() & pSubnet->IpNetMask()))
3473 {
3474 if (pCluster != NULL)
3475 {
58b3e451 3476 if (pCluster->isSyncAddr(m_pChildList[j]->IpAddr()))
5039dede
AK
3477 {
3478 j = (int)m_dwChildCount; // Cause to unbind from this subnet
3479 }
3480 }
3481 break;
3482 }
3483 }
3484 }
3485 if (j == (int)m_dwChildCount)
3486 {
3487 DbgPrintf(4, _T("Node::CheckSubnetBinding(): Subnet %s [%d] is incorrect for node %s [%d]"),
3488 pSubnet->Name(), pSubnet->Id(), m_szName, m_dwId);
3489 ppUnlinkList[count++] = pSubnet;
3490 }
3491 }
3492 }
3493 UnlockChildList();
3494 UnlockParentList();
3495
3496 // Unlink for incorrect subnet objects
3497 for(i = 0; i < count; i++)
3498 {
3499 ppUnlinkList[i]->DeleteChild(this);
3500 DeleteParent(ppUnlinkList[i]);
3501 }
3502 safe_free(ppUnlinkList);
3503}
3504
3505
3506//
3507// Update interface names
3508//
3509
58b3e451 3510void Node::updateInterfaceNames(ClientSession *pSession, DWORD dwRqId)
5039dede
AK
3511{
3512 INTERFACE_LIST *pIfList;
3513 DWORD i;
3514 int j;
3515
7c521895 3516 pollerLock();
5039dede
AK
3517 m_pPollRequestor = pSession;
3518 SendPollerMsg(dwRqId, _T("Starting interface names poll for node %s\r\n"), m_szName);
3519 DbgPrintf(4, "Starting interface names poll for node %s (ID: %d)", m_szName, m_dwId);
3520
3521 // Retrieve interface list
58b3e451 3522 pIfList = getInterfaceList();
5039dede
AK
3523 if (pIfList != NULL)
3524 {
3525 // Check names of existing interfaces
3526 for(j = 0; j < pIfList->iNumEntries; j++)
3527 {
3528 LockChildList(FALSE);
3529 for(i = 0; i < m_dwChildCount; i++)
3530 {
3531 if (m_pChildList[i]->Type() == OBJECT_INTERFACE)
3532 {
3533 Interface *pInterface = (Interface *)m_pChildList[i];
3534
3535 if (pIfList->pInterfaces[j].dwIndex == pInterface->IfIndex())
3536 {
3537 SendPollerMsg(dwRqId, _T(" Checking interface %d (%s)\r\n"), pInterface->IfIndex(), pInterface->Name());
3538 if (strcmp(pIfList->pInterfaces[j].szName, pInterface->Name()))
3539 {
3540 pInterface->SetName(pIfList->pInterfaces[j].szName);
3541 SendPollerMsg(dwRqId, POLLER_WARNING _T(" Name of interface %d changed to %s\r\n"), pInterface->IfIndex(), pIfList->pInterfaces[j].szName);
3542 }
3543 break;
3544 }
3545 }
3546 }
3547 UnlockChildList();
3548 }
3549
3550 DestroyInterfaceList(pIfList);
3551 }
3552 else /* pIfList == NULL */
3553 {
3554 SendPollerMsg(dwRqId, POLLER_ERROR _T(" Unable to get interface list from node\r\n"));
3555 }
3556
3557 // Finish poll
3558 SendPollerMsg(dwRqId, _T("Finished interface names poll for node %s\r\n"), m_szName);
7c521895 3559 pollerUnlock();
5039dede
AK
3560 DbgPrintf(4, "Finished interface names poll for node %s (ID: %d)", m_szName, m_dwId);
3561}
a2069340
VK
3562
3563
3564//
3565// Process new DCI value
3566//
3567
3568void Node::processNewDciValue(DCItem *item, time_t currTime, const TCHAR *value)
3569{
3570 lockDciAccess();
3571 item->processNewValue(currTime, value);
3572 unlockDciAccess();
3573}
501b7b03
VK
3574
3575
3576//
3577// Get list of parent objects for NXSL script
3578//
3579
3580NXSL_Array *Node::getParentsForNXSL()
3581{
3582 NXSL_Array *parents = new NXSL_Array;
3583 int index = 0;
3584
3585 LockParentList(FALSE);
3586 for(DWORD i = 0; i < m_dwParentCount; i++)
3587 {
3588 if (((m_pParentList[i]->Type() == OBJECT_CONTAINER) ||
3589 (m_pParentList[i]->Type() == OBJECT_CLUSTER) ||
3590 (m_pParentList[i]->Type() == OBJECT_SUBNET) ||
3591 (m_pParentList[i]->Type() == OBJECT_SERVICEROOT)) &&
3592 m_pParentList[i]->IsTrustedNode(m_dwId))
3593 {
541a3ebc 3594 parents->set(index++, new NXSL_Value(new NXSL_Object(&g_nxslNetObjClass, m_pParentList[i])));
501b7b03
VK
3595 }
3596 }
3597 UnlockParentList();
3598
3599 return parents;
3600}