+ http checker
[public/netxms.git] / src / server / core / node.cpp
CommitLineData
eefe7d68 1/*
1275c750 2** NetXMS - Network Management System
b50f1100 3** Copyright (C) 2003, 2004 Victor Kirhenshtein
eefe7d68
VK
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** $module: node.cpp
20**
21**/
22
a551fe4d 23#include "nxcore.h"
eefe7d68
VK
24
25
26//
27// Node class default constructor
28//
29
30Node::Node()
b50f1100 31 :Template()
eefe7d68
VK
32{
33 m_dwFlags = 0;
34 m_dwDiscoveryFlags = 0;
4e839863 35 m_dwDynamicFlags = 0;
18e26ff8 36 m_dwNodeType = NODE_TYPE_GENERIC;
2da1357c
VK
37 m_wAgentPort = AGENT_LISTEN_PORT;
38 m_wAuthMethod = AUTH_NONE;
39 m_szSharedSecret[0] = 0;
40 m_iStatusPollType = POLL_ICMP_PING;
469b937c 41 m_iSNMPVersion = SNMP_VERSION_1;
2da1357c 42 strcpy(m_szCommunityString, "public");
469b937c 43 m_szObjectId[0] = 0;
48b1c0ac 44 m_tLastDiscoveryPoll = 0;
f00307b7 45 m_tLastStatusPoll = 0;
364aa19a
VK
46 m_tLastConfigurationPoll = 0;
47 m_iSnmpAgentFails = 0;
48 m_iNativeAgentFails = 0;
323f8bec 49 m_hPollerMutex = MutexCreate();
3ea35b38 50 m_hAgentAccessMutex = MutexCreate();
1275c750 51 m_pAgentConnection = NULL;
ae3a55d9 52 m_szAgentVersion[0] = 0;
1c8b8363 53 m_szPlatformName[0] = 0;
89235715
VK
54 m_dwNumParams = 0;
55 m_pParamList = NULL;
eefe7d68
VK
56}
57
58
59//
60// Constructor for new node object
61//
62
63Node::Node(DWORD dwAddr, DWORD dwFlags, DWORD dwDiscoveryFlags)
b50f1100 64 :Template()
eefe7d68
VK
65{
66 m_dwIpAddr = dwAddr;
67 m_dwFlags = dwFlags;
4e839863 68 m_dwDynamicFlags = 0;
18e26ff8 69 m_dwNodeType = NODE_TYPE_GENERIC;
eefe7d68 70 m_dwDiscoveryFlags = dwDiscoveryFlags;
2da1357c
VK
71 m_wAgentPort = AGENT_LISTEN_PORT;
72 m_wAuthMethod = AUTH_NONE;
73 m_szSharedSecret[0] = 0;
74 m_iStatusPollType = POLL_ICMP_PING;
469b937c 75 m_iSNMPVersion = SNMP_VERSION_1;
2da1357c 76 strcpy(m_szCommunityString, "public");
cc140cce 77 IpToStr(dwAddr, m_szName); // Make default name from IP address
469b937c 78 m_szObjectId[0] = 0;
48b1c0ac 79 m_tLastDiscoveryPoll = 0;
f00307b7 80 m_tLastStatusPoll = 0;
364aa19a
VK
81 m_tLastConfigurationPoll = 0;
82 m_iSnmpAgentFails = 0;
83 m_iNativeAgentFails = 0;
323f8bec 84 m_hPollerMutex = MutexCreate();
3ea35b38 85 m_hAgentAccessMutex = MutexCreate();
1275c750 86 m_pAgentConnection = NULL;
ae3a55d9 87 m_szAgentVersion[0] = 0;
1c8b8363 88 m_szPlatformName[0] = 0;
89235715
VK
89 m_dwNumParams = 0;
90 m_pParamList = NULL;
eefe7d68
VK
91}
92
93
94//
95// Node destructor
96//
97
98Node::~Node()
99{
323f8bec 100 MutexDestroy(m_hPollerMutex);
3ea35b38 101 MutexDestroy(m_hAgentAccessMutex);
1275c750
VK
102 if (m_pAgentConnection != NULL)
103 delete m_pAgentConnection;
89235715 104 safe_free(m_pParamList);
eefe7d68
VK
105}
106
107
2da1357c
VK
108//
109// Create object from database data
110//
111
112BOOL Node::CreateFromDB(DWORD dwId)
113{
ae3a55d9 114 char szQuery[512];
2da1357c
VK
115 DB_RESULT hResult;
116 int i, iNumRows;
117 DWORD dwSubnetId;
118 NetObj *pObject;
333ece94 119 BOOL bResult = FALSE;
2da1357c 120
ae3a55d9
VK
121 _sntprintf(szQuery, 512, "SELECT id,name,status,primary_ip,is_snmp,is_agent,is_bridge,"
122 "is_router,snmp_version,discovery_flags,auth_method,secret,"
123 "agent_port,status_poll_type,community,snmp_oid,is_local_mgmt,"
d4c266b6
VK
124 "image_id,is_deleted,description,node_type,agent_version,"
125 "platform_name FROM nodes WHERE id=%d", dwId);
2da1357c
VK
126 hResult = DBSelect(g_hCoreDB, szQuery);
127 if (hResult == 0)
128 return FALSE; // Query failed
129
130 if (DBGetNumRows(hResult) == 0)
131 {
132 DBFreeResult(hResult);
133 return FALSE;
134 }
135
136 m_dwId = dwId;
137 strncpy(m_szName, DBGetField(hResult, 0, 1), MAX_OBJECT_NAME);
138 m_iStatus = DBGetFieldLong(hResult, 0, 2);
205acaf4 139 m_dwIpAddr = DBGetFieldIPAddr(hResult, 0, 3);
2da1357c
VK
140
141 // Flags
142 if (DBGetFieldLong(hResult, 0, 4))
143 m_dwFlags |= NF_IS_SNMP;
144 if (DBGetFieldLong(hResult, 0, 5))
145 m_dwFlags |= NF_IS_NATIVE_AGENT;
146 if (DBGetFieldLong(hResult, 0, 6))
147 m_dwFlags |= NF_IS_BRIDGE;
148 if (DBGetFieldLong(hResult, 0, 7))
149 m_dwFlags |= NF_IS_ROUTER;
ce19c304
VK
150 if (DBGetFieldLong(hResult, 0, 16))
151 m_dwFlags |= NF_IS_LOCAL_MGMT;
2da1357c
VK
152
153 m_iSNMPVersion = DBGetFieldLong(hResult, 0, 8);
154 m_dwDiscoveryFlags = DBGetFieldULong(hResult, 0, 9);
155 m_wAuthMethod = (WORD)DBGetFieldLong(hResult, 0, 10);
156 strncpy(m_szSharedSecret, DBGetField(hResult, 0, 11), MAX_SECRET_LENGTH);
157 m_wAgentPort = (WORD)DBGetFieldLong(hResult, 0, 12);
158 m_iStatusPollType = DBGetFieldLong(hResult, 0, 13);
159 strncpy(m_szCommunityString, DBGetField(hResult, 0, 14), MAX_COMMUNITY_LENGTH);
a0495b6e 160 strncpy(m_szObjectId, DBGetField(hResult, 0, 15), MAX_OID_LEN * 4);
cb151d1e 161 m_dwImageId = DBGetFieldULong(hResult, 0, 17);
333ece94 162 m_bIsDeleted = DBGetFieldLong(hResult, 0, 18);
18e26ff8
VK
163 m_pszDescription = _tcsdup(CHECK_NULL_EX(DBGetField(hResult, 0, 19)));
164 DecodeSQLString(m_pszDescription);
165 m_dwNodeType = DBGetFieldULong(hResult, 0, 20);
ae3a55d9
VK
166 _tcsncpy(m_szAgentVersion, CHECK_NULL_EX(DBGetField(hResult, 0, 21)), MAX_AGENT_VERSION_LEN);
167 DecodeSQLString(m_szAgentVersion);
d4c266b6
VK
168 _tcsncpy(m_szPlatformName, CHECK_NULL_EX(DBGetField(hResult, 0, 22)), MAX_PLATFORM_NAME_LEN);
169 DecodeSQLString(m_szPlatformName);
2da1357c
VK
170
171 DBFreeResult(hResult);
172
333ece94 173 if (!m_bIsDeleted)
2da1357c 174 {
333ece94
VK
175 // Link node to subnets
176 sprintf(szQuery, "SELECT subnet_id FROM nsmap WHERE node_id=%d", dwId);
177 hResult = DBSelect(g_hCoreDB, szQuery);
178 if (hResult == NULL)
179 return FALSE; // Query failed
2da1357c 180
333ece94 181 if (DBGetNumRows(hResult) == 0)
2da1357c 182 {
333ece94
VK
183 DBFreeResult(hResult);
184 return FALSE; // No parents - it shouldn't happen if database isn't corrupted
2da1357c 185 }
333ece94
VK
186
187 iNumRows = DBGetNumRows(hResult);
188 for(i = 0; i < iNumRows; i++)
2da1357c 189 {
333ece94
VK
190 dwSubnetId = DBGetFieldULong(hResult, i, 0);
191 pObject = FindObjectById(dwSubnetId);
192 if (pObject == NULL)
193 {
194 WriteLog(MSG_INVALID_SUBNET_ID, EVENTLOG_ERROR_TYPE, "dd", dwId, dwSubnetId);
195 break;
196 }
197 else if (pObject->Type() != OBJECT_SUBNET)
198 {
199 WriteLog(MSG_SUBNET_NOT_SUBNET, EVENTLOG_ERROR_TYPE, "dd", dwId, dwSubnetId);
200 break;
201 }
202 else
203 {
204 pObject->AddChild(this);
205 AddParent(pObject);
206 bResult = TRUE;
207 }
2da1357c 208 }
2da1357c 209
333ece94
VK
210 DBFreeResult(hResult);
211 LoadItemsFromDB();
212 LoadACLFromDB();
3ea35b38 213
333ece94
VK
214 // Walk through all items in the node and load appropriate thresholds
215 for(i = 0; i < (int)m_dwNumItems; i++)
216 if (!m_ppItems[i]->LoadThresholdsFromDB())
217 bResult = FALSE;
218 }
219 else
220 {
221 bResult = TRUE;
222 }
3ea35b38 223
cc140cce 224 return bResult;
2da1357c
VK
225}
226
227
eefe7d68
VK
228//
229// Save object to database
230//
231
232BOOL Node::SaveToDB(void)
233{
d4c266b6
VK
234 TCHAR *pszEscDescr, *pszEscVersion, *pszEscPlatform;
235 TCHAR szQuery[4096], szIpAddr[16];
eefe7d68
VK
236 DB_RESULT hResult;
237 BOOL bNewObject = TRUE;
3ea35b38 238 BOOL bResult;
eefe7d68
VK
239
240 // Lock object's access
241 Lock();
242
243 // Check for object's existence in database
244 sprintf(szQuery, "SELECT id FROM nodes WHERE id=%ld", m_dwId);
245 hResult = DBSelect(g_hCoreDB, szQuery);
246 if (hResult != 0)
247 {
248 if (DBGetNumRows(hResult) > 0)
249 bNewObject = FALSE;
250 DBFreeResult(hResult);
251 }
252
253 // Form and execute INSERT or UPDATE query
18e26ff8 254 pszEscDescr = EncodeSQLString(CHECK_NULL_EX(m_pszDescription));
ae3a55d9 255 pszEscVersion = EncodeSQLString(m_szAgentVersion);
d4c266b6 256 pszEscPlatform = EncodeSQLString(m_szPlatformName);
eefe7d68 257 if (bNewObject)
d4c266b6
VK
258 snprintf(szQuery, 4096,
259 "INSERT INTO nodes (id,name,status,is_deleted,primary_ip,"
260 "is_snmp,is_agent,is_bridge,is_router,snmp_version,community,"
261 "discovery_flags,status_poll_type,agent_port,auth_method,secret,"
262 "snmp_oid,is_local_mgmt,image_id,description,node_type,"
263 "agent_version,platform_name)"
264 " VALUES (%d,'%s',%d,%d,'%s',%d,%d,%d,%d,%d,'%s',%d,%d,%d,%d,"
265 "'%s','%s',%d,%ld,'%s',%ld,'%s','%s')",
266 m_dwId, m_szName, m_iStatus, m_bIsDeleted,
267 IpToStr(m_dwIpAddr, szIpAddr),
268 m_dwFlags & NF_IS_SNMP ? 1 : 0,
269 m_dwFlags & NF_IS_NATIVE_AGENT ? 1 : 0,
270 m_dwFlags & NF_IS_BRIDGE ? 1 : 0,
271 m_dwFlags & NF_IS_ROUTER ? 1 : 0,
272 m_iSNMPVersion, m_szCommunityString, m_dwDiscoveryFlags, m_iStatusPollType,
273 m_wAgentPort,m_wAuthMethod,m_szSharedSecret, m_szObjectId,
274 m_dwFlags & NF_IS_LOCAL_MGMT ? 1 : 0, m_dwImageId,
275 pszEscDescr, m_dwNodeType, pszEscVersion, pszEscPlatform);
eefe7d68 276 else
d4c266b6
VK
277 snprintf(szQuery, 4096,
278 "UPDATE nodes SET name='%s',status=%d,is_deleted=%d,primary_ip='%s',"
279 "is_snmp=%d,is_agent=%d,is_bridge=%d,is_router=%d,snmp_version=%d,"
280 "community='%s',discovery_flags=%d,status_poll_type=%d,agent_port=%d,"
281 "auth_method=%d,secret='%s',snmp_oid='%s',is_local_mgmt=%d,"
282 "image_id=%ld,description='%s',node_type=%ld,agent_version='%s',"
283 "platform_name='%s' WHERE id=%ld",
284 m_szName, m_iStatus, m_bIsDeleted,
285 IpToStr(m_dwIpAddr, szIpAddr),
286 m_dwFlags & NF_IS_SNMP ? 1 : 0,
287 m_dwFlags & NF_IS_NATIVE_AGENT ? 1 : 0,
288 m_dwFlags & NF_IS_BRIDGE ? 1 : 0,
289 m_dwFlags & NF_IS_ROUTER ? 1 : 0,
290 m_iSNMPVersion, m_szCommunityString, m_dwDiscoveryFlags,
291 m_iStatusPollType, m_wAgentPort, m_wAuthMethod, m_szSharedSecret,
292 m_szObjectId, m_dwFlags & NF_IS_LOCAL_MGMT ? 1 : 0, m_dwImageId,
293 pszEscDescr, m_dwNodeType, pszEscVersion, pszEscPlatform, m_dwId);
3ea35b38 294 bResult = DBQuery(g_hCoreDB, szQuery);
18e26ff8 295 free(pszEscDescr);
ae3a55d9 296 free(pszEscVersion);
d4c266b6 297 free(pszEscPlatform);
3ea35b38
VK
298
299 // Save data collection items
300 if (bResult)
301 {
302 DWORD i;
303
304 for(i = 0; i < m_dwNumItems; i++)
305 m_ppItems[i]->SaveToDB();
306 }
eefe7d68 307
de78f964
VK
308 // Save access list
309 SaveACLToDB();
310
eefe7d68
VK
311 // Clear modifications flag and unlock object
312 m_bIsModified = FALSE;
313 Unlock();
314
3ea35b38 315 return bResult;
eefe7d68
VK
316}
317
318
319//
320// Delete object from database
321//
322
323BOOL Node::DeleteFromDB(void)
324{
325 char szQuery[256];
ef44d5ea 326 BOOL bSuccess;
eefe7d68 327
b50f1100 328 bSuccess = Template::DeleteFromDB();
ef44d5ea
VK
329 if (bSuccess)
330 {
331 sprintf(szQuery, "DELETE FROM nodes WHERE id=%ld", m_dwId);
332 QueueSQLRequest(szQuery);
333 sprintf(szQuery, "DELETE FROM nsmap WHERE node_id=%ld", m_dwId);
334 QueueSQLRequest(szQuery);
335 sprintf(szQuery, "DROP TABLE idata_%ld", m_dwId);
336 QueueSQLRequest(szQuery);
337 }
338 return bSuccess;
eefe7d68 339}
469b937c
VK
340
341
342//
343// Poll newly discovered node
344// Usually called once by node poller thread when new node is discovered
345// and object for it is created
346//
347
1a4e3eff 348void Node::NewNodePoll(DWORD dwNetMask)
469b937c 349{
5811233f
VK
350 AgentConnection *pAgentConn;
351
be0a5a53
VK
352 PollerLock();
353
469b937c 354 // Determine node's capabilities
3d1cb7d6 355 if (SnmpGet(SNMP_VERSION_2C, m_dwIpAddr, m_szCommunityString, ".1.3.6.1.2.1.1.2.0", NULL, 0,
80de4676 356 m_szObjectId, MAX_OID_LEN * 4, FALSE, FALSE) == SNMP_ERR_SUCCESS)
18e26ff8
VK
357 {
358 DWORD dwNodeFlags;
359
360 m_dwNodeType = OidToType(m_szObjectId, &dwNodeFlags);
361 m_dwFlags |= NF_IS_SNMP | dwNodeFlags;
3d1cb7d6 362 m_iSNMPVersion = SNMP_VERSION_2C;
37c4d6aa
VK
363 }
364 else
365 {
366 if (SnmpGet(SNMP_VERSION_1, m_dwIpAddr, m_szCommunityString, ".1.3.6.1.2.1.1.2.0", NULL, 0,
80de4676 367 m_szObjectId, MAX_OID_LEN * 4, FALSE, FALSE) == SNMP_ERR_SUCCESS)
37c4d6aa
VK
368 {
369 DWORD dwNodeFlags;
370
371 m_dwNodeType = OidToType(m_szObjectId, &dwNodeFlags);
372 m_dwFlags |= NF_IS_SNMP | dwNodeFlags;
373 m_iSNMPVersion = SNMP_VERSION_1;
374 }
18e26ff8 375 }
469b937c 376
205acaf4 377 pAgentConn = new AgentConnection(htonl(m_dwIpAddr), m_wAgentPort, m_wAuthMethod,
a7b85168 378 m_szSharedSecret);
5811233f 379 if (pAgentConn->Connect())
ae3a55d9 380 {
5811233f 381 m_dwFlags |= NF_IS_NATIVE_AGENT;
ae3a55d9 382 pAgentConn->GetParameter("Agent.Version", MAX_AGENT_VERSION_LEN, m_szAgentVersion);
1c8b8363 383 pAgentConn->GetParameter("System.PlatformName", MAX_PLATFORM_NAME_LEN, m_szPlatformName);
89235715
VK
384
385 pAgentConn->GetSupportedParameters(&m_dwNumParams, &m_pParamList);
ae3a55d9 386 }
5811233f 387
469b937c 388 // Get interface list
a7b85168
VK
389 if ((m_dwFlags & NF_IS_SNMP) || (m_dwFlags & NF_IS_NATIVE_AGENT) ||
390 (m_dwFlags & NF_IS_LOCAL_MGMT))
469b937c 391 {
5811233f 392 INTERFACE_LIST *pIfList = NULL;
a0495b6e
VK
393 int i;
394
ce19c304
VK
395 if (m_dwFlags & NF_IS_LOCAL_MGMT) // For local machine
396 pIfList = GetLocalInterfaceList();
397 else if (m_dwFlags & NF_IS_NATIVE_AGENT) // For others prefer native agent
fd5aa295 398 {
5811233f 399 pIfList = pAgentConn->GetInterfaceList();
fd5aa295
VK
400 CleanInterfaceList(pIfList);
401 }
5811233f 402 if ((pIfList == NULL) && (m_dwFlags & NF_IS_SNMP)) // Use SNMP if we cannot get interfaces via agent
37c4d6aa 403 pIfList = SnmpGetInterfaceList(m_iSNMPVersion, m_dwIpAddr, m_szCommunityString, m_dwNodeType);
5811233f
VK
404
405 if (pIfList != NULL)
a0495b6e 406 {
5811233f 407 for(i = 0; i < pIfList->iNumEntries; i++)
323f8bec
VK
408 CreateNewInterface(pIfList->pInterfaces[i].dwIpAddr,
409 pIfList->pInterfaces[i].dwIpNetMask,
410 pIfList->pInterfaces[i].szName,
411 pIfList->pInterfaces[i].dwIndex,
b50f1100
VK
412 pIfList->pInterfaces[i].dwType,
413 pIfList->pInterfaces[i].bMacAddr);
5811233f 414 DestroyInterfaceList(pIfList);
a0495b6e 415 }
9437ca82
VK
416 else
417 {
418 // We cannot get interface list from node for some reasons, create dummy one
323f8bec 419 CreateNewInterface(m_dwIpAddr, dwNetMask);
9437ca82 420 }
469b937c
VK
421 }
422 else // No SNMP, no native agent - create pseudo interface object
423 {
323f8bec 424 CreateNewInterface(m_dwIpAddr, dwNetMask);
469b937c
VK
425 }
426
5811233f
VK
427 // Clean up agent connection
428 if (m_dwFlags & NF_IS_NATIVE_AGENT)
429 pAgentConn->Disconnect();
430 delete pAgentConn;
431
be0a5a53 432 PollerUnlock();
469b937c 433}
ce19c304
VK
434
435
436//
c8b1f788 437// Get ARP cache from node
ce19c304
VK
438//
439
c8b1f788 440ARP_CACHE *Node::GetArpCache(void)
ce19c304
VK
441{
442 ARP_CACHE *pArpCache = NULL;
443
444 if (m_dwFlags & NF_IS_LOCAL_MGMT)
445 {
446 pArpCache = GetLocalArpCache();
447 }
448 else if (m_dwFlags & NF_IS_NATIVE_AGENT)
449 {
3ea35b38 450 AgentLock();
1275c750
VK
451 if (ConnectToAgent())
452 pArpCache = m_pAgentConnection->GetArpCache();
3ea35b38 453 AgentUnlock();
ce19c304
VK
454 }
455 else if (m_dwFlags & NF_IS_SNMP)
456 {
37c4d6aa 457 pArpCache = SnmpGetArpCache(m_iSNMPVersion, m_dwIpAddr, m_szCommunityString);
ce19c304
VK
458 }
459
460 return pArpCache;
461}
462
463
464//
465// Get list of interfaces from node
466//
467
468INTERFACE_LIST *Node::GetInterfaceList(void)
469{
470 INTERFACE_LIST *pIfList = NULL;
471
472 if (m_dwFlags & NF_IS_LOCAL_MGMT)
473 {
474 pIfList = GetLocalInterfaceList();
475 }
476 else if (m_dwFlags & NF_IS_NATIVE_AGENT)
477 {
1c62be36
VK
478 AgentLock();
479 if (ConnectToAgent())
ce19c304 480 {
1c62be36 481 pIfList = m_pAgentConnection->GetInterfaceList();
fd5aa295 482 CleanInterfaceList(pIfList);
ce19c304 483 }
1c62be36 484 AgentUnlock();
ce19c304
VK
485 }
486 else if (m_dwFlags & NF_IS_SNMP)
487 {
37c4d6aa 488 pIfList = SnmpGetInterfaceList(m_iSNMPVersion, m_dwIpAddr, m_szCommunityString, m_dwNodeType);
ce19c304
VK
489 }
490
491 return pIfList;
492}
48b1c0ac
VK
493
494
495//
496// Find interface by index and node IP
497// Returns pointer to interface object or NULL if appropriate interface couldn't be found
498//
499
500Interface *Node::FindInterface(DWORD dwIndex, DWORD dwHostAddr)
501{
502 DWORD i;
503 Interface *pInterface;
504
c695e7e3 505 Lock();
48b1c0ac
VK
506 for(i = 0; i < m_dwChildCount; i++)
507 if (m_pChildList[i]->Type() == OBJECT_INTERFACE)
508 {
509 pInterface = (Interface *)m_pChildList[i];
510 if (pInterface->IfIndex() == dwIndex)
205acaf4 511 {
48b1c0ac
VK
512 if ((pInterface->IpAddr() & pInterface->IpNetMask()) ==
513 (dwHostAddr & pInterface->IpNetMask()))
c695e7e3
VK
514 {
515 Unlock();
48b1c0ac 516 return pInterface;
c695e7e3 517 }
205acaf4 518 }
48b1c0ac 519 }
c695e7e3 520 Unlock();
48b1c0ac
VK
521 return NULL;
522}
f00307b7
VK
523
524
323f8bec
VK
525//
526// Create new interface
527//
528
b50f1100
VK
529void Node::CreateNewInterface(DWORD dwIpAddr, DWORD dwNetMask, char *szName,
530 DWORD dwIndex, DWORD dwType, BYTE *pbMacAddr)
323f8bec
VK
531{
532 Interface *pInterface;
28fbe2be 533 Subnet *pSubnet = NULL;
323f8bec 534
c695e7e3
VK
535 // Find subnet to place interface object to
536 if (dwIpAddr != 0)
537 {
538 pSubnet = FindSubnetForNode(dwIpAddr);
539 if (pSubnet == NULL)
540 {
541 // Check if netmask is 0 (detect), and if yes, create
542 // new subnet with class mask
543 if (dwNetMask == 0)
544 {
205acaf4
VK
545 if (dwIpAddr < 0x80000000)
546 dwNetMask = 0xFF000000; // Class A
547 else if (dwIpAddr < 0xC0000000)
548 dwNetMask = 0xFFFF0000; // Class B
549 else if (dwIpAddr < 0xE0000000)
550 dwNetMask = 0xFFFFFF00; // Class C
c695e7e3
VK
551 else
552 {
28fbe2be
VK
553 TCHAR szBuffer[16];
554
c695e7e3
VK
555 // Multicast address??
556 DbgPrintf(AF_DEBUG_DISCOVERY,
557 "Attempt to create interface object with multicast address %s",
28fbe2be 558 IpToStr(dwIpAddr, szBuffer));
c695e7e3
VK
559 }
560 }
561
562 // Create new subnet object
205acaf4 563 if (dwIpAddr < 0xE0000000)
28fbe2be
VK
564 {
565 pSubnet = new Subnet(dwIpAddr & dwNetMask, dwNetMask);
566 NetObjInsert(pSubnet, TRUE);
567 g_pEntireNet->AddSubnet(pSubnet);
568 }
c695e7e3
VK
569 }
570 else
571 {
572 // Set correct netmask if we was asked for it
573 if (dwNetMask == 0)
574 {
575 dwNetMask = pSubnet->IpNetMask();
576 }
577 }
578 }
579
323f8bec
VK
580 // Create interface object
581 if (szName != NULL)
582 pInterface = new Interface(szName, dwIndex, dwIpAddr, dwNetMask, dwType);
583 else
584 pInterface = new Interface(dwIpAddr, dwNetMask);
b50f1100
VK
585 if (pbMacAddr != NULL)
586 pInterface->SetMacAddr(pbMacAddr);
323f8bec
VK
587
588 // Insert to objects' list and generate event
589 NetObjInsert(pInterface, TRUE);
590 AddInterface(pInterface);
591 PostEvent(EVENT_INTERFACE_ADDED, m_dwId, "dsaad", pInterface->Id(),
592 pInterface->Name(), pInterface->IpAddr(),
593 pInterface->IpNetMask(), pInterface->IfIndex());
594
595 // Bind node to appropriate subnet
28fbe2be 596 if (pSubnet != NULL)
323f8bec 597 {
323f8bec 598 pSubnet->AddNode(this);
28fbe2be
VK
599
600 // Check if subnet mask is correct on interface
601 if (pSubnet->IpNetMask() != dwNetMask)
602 PostEvent(EVENT_INCORRECT_NETMASK, m_dwId, "idsaa", pInterface->Id(),
603 pInterface->IfIndex(), pInterface->Name(),
604 pInterface->IpNetMask(), pSubnet->IpNetMask());
323f8bec
VK
605 }
606}
607
608
609//
610// Delete interface from node
611//
612
613void Node::DeleteInterface(Interface *pInterface)
614{
615 DWORD i;
616
617 // Check if we should unlink node from interface's subnet
618 if (pInterface->IpAddr() != 0)
619 {
620 for(i = 0; i < m_dwChildCount; i++)
621 if (m_pChildList[i]->Type() == OBJECT_INTERFACE)
622 if (m_pChildList[i] != pInterface)
623 if ((((Interface *)m_pChildList[i])->IpAddr() & ((Interface *)m_pChildList[i])->IpNetMask()) ==
624 (pInterface->IpAddr() & pInterface->IpNetMask()))
625 break;
626 if (i == m_dwChildCount)
627 {
628 // Last interface in subnet, should unlink node
629 Subnet *pSubnet = FindSubnetByIP(pInterface->IpAddr() & pInterface->IpNetMask());
3ea35b38 630 DeleteParent(pSubnet);
323f8bec 631 if (pSubnet != NULL)
3ea35b38 632 {
323f8bec 633 pSubnet->DeleteChild(this);
3ea35b38
VK
634 if ((pSubnet->IsEmpty()) && (g_dwFlags & AF_DELETE_EMPTY_SUBNETS))
635 {
636 PostEvent(EVENT_SUBNET_DELETED, pSubnet->Id(), NULL);
637 pSubnet->Delete();
638 }
639 }
323f8bec
VK
640 }
641 }
642 pInterface->Delete();
643}
644
645
f00307b7
VK
646//
647// Calculate node status based on child objects status
648//
649
650void Node::CalculateCompoundStatus(void)
651{
652 int iOldStatus = m_iStatus;
653 static DWORD dwEventCodes[] = { EVENT_NODE_NORMAL, EVENT_NODE_MINOR,
654 EVENT_NODE_WARNING, EVENT_NODE_MAJOR, EVENT_NODE_CRITICAL,
655 EVENT_NODE_UNKNOWN, EVENT_NODE_UNMANAGED };
656
657 NetObj::CalculateCompoundStatus();
658 if (m_iStatus != iOldStatus)
659 PostEvent(dwEventCodes[m_iStatus], m_dwId, "d", iOldStatus);
660}
661
662
663//
664// Perform status poll on node
665//
666
d966d18a 667void Node::StatusPoll(ClientSession *pSession, DWORD dwRqId)
f00307b7
VK
668{
669 DWORD i;
670
323f8bec 671 PollerLock();
eb8b1960 672 m_pPollRequestor = pSession;
0ba90743 673 SendPollerMsg(dwRqId, _T("Starting status poll for node %s\r\n"), m_szName);
f00307b7 674 for(i = 0; i < m_dwChildCount; i++)
c1c39152
VK
675 if ((m_pChildList[i]->Type() == OBJECT_INTERFACE) &&
676 (m_pChildList[i]->Status() != STATUS_UNMANAGED))
d966d18a 677 ((Interface *)m_pChildList[i])->StatusPoll(pSession, dwRqId);
f00307b7
VK
678 CalculateCompoundStatus();
679 m_tLastStatusPoll = time(NULL);
d966d18a
VK
680 SendPollerMsg(dwRqId, "Finished status poll for node %s\r\n"
681 "Node status after poll is %s\r\n", m_szName, g_pszStatusName[m_iStatus]);
eb8b1960 682 m_pPollRequestor = NULL;
4e839863 683 m_dwDynamicFlags &= ~NDF_QUEUED_FOR_STATUS_POLL;
323f8bec 684 PollerUnlock();
f00307b7 685}
364aa19a
VK
686
687
688//
689// Perform configuration poll on node
690//
691
0ba90743 692void Node::ConfigurationPoll(ClientSession *pSession, DWORD dwRqId)
364aa19a
VK
693{
694 DWORD dwOldFlags = m_dwFlags;
695 AgentConnection *pAgentConn;
696 INTERFACE_LIST *pIfList;
6159a875 697 BOOL bHasChanges = FALSE;
364aa19a 698
323f8bec 699 PollerLock();
0ba90743 700 m_pPollRequestor = pSession;
a098be0b 701 SendPollerMsg(dwRqId, _T("Starting configuration poll for node %s\r\n"), m_szName);
b1dd534d 702 DbgPrintf(AF_DEBUG_DISCOVERY, "Starting configuration poll for node %s (ID: %d)", m_szName, m_dwId);
323f8bec 703
364aa19a 704 // Check node's capabilities
0ba90743 705 SendPollerMsg(dwRqId, _T("Checking node's capabilities...\r\n"));
498ccc60
VK
706 if (SnmpGet(m_iSNMPVersion, m_dwIpAddr, m_szCommunityString, ".1.3.6.1.2.1.1.2.0", NULL, 0,
707 m_szObjectId, MAX_OID_LEN * 4, FALSE, FALSE) == SNMP_ERR_SUCCESS)
364aa19a 708 {
18e26ff8
VK
709 DWORD dwNodeFlags, dwNodeType;
710
364aa19a
VK
711 m_dwFlags |= NF_IS_SNMP;
712 m_iSnmpAgentFails = 0;
0ba90743 713 SendPollerMsg(dwRqId, _T(" SNMP agent is active\r\n"));
18e26ff8
VK
714
715 // Check node type
716 dwNodeType = OidToType(m_szObjectId, &dwNodeFlags);
717 if (m_dwNodeType != dwNodeType)
718 {
719 m_dwFlags |= dwNodeFlags;
720 m_dwNodeType = dwNodeType;
721 SendPollerMsg(dwRqId, _T(" Node type has been changed to %d\r\n"), m_dwNodeType);
722 }
364aa19a
VK
723 }
724 else
725 {
4ea67c99
VK
726 if (m_dwFlags & NF_IS_SNMP)
727 {
728 if (m_iSnmpAgentFails == 0)
729 PostEvent(EVENT_SNMP_FAIL, m_dwId, NULL);
730 m_iSnmpAgentFails++;
731 }
0ba90743 732 SendPollerMsg(dwRqId, _T(" SNMP agent is not responding\r\n"));
364aa19a
VK
733 }
734
205acaf4 735 pAgentConn = new AgentConnection(htonl(m_dwIpAddr), m_wAgentPort, m_wAuthMethod, m_szSharedSecret);
364aa19a
VK
736 if (pAgentConn->Connect())
737 {
738 m_dwFlags |= NF_IS_NATIVE_AGENT;
739 m_iNativeAgentFails = 0;
89235715
VK
740
741 Lock();
ae3a55d9 742 pAgentConn->GetParameter("Agent.Version", MAX_AGENT_VERSION_LEN, m_szAgentVersion);
1c8b8363 743 pAgentConn->GetParameter("System.PlatformName", MAX_PLATFORM_NAME_LEN, m_szPlatformName);
89235715
VK
744
745 safe_free(m_pParamList);
746 pAgentConn->GetSupportedParameters(&m_dwNumParams, &m_pParamList);
747
748 Unlock();
f91fa4c2 749 pAgentConn->Disconnect();
0ba90743 750 SendPollerMsg(dwRqId, _T(" NetXMS native agent is active\r\n"));
364aa19a
VK
751 }
752 else
753 {
4ea67c99
VK
754 if (m_dwFlags & NF_IS_NATIVE_AGENT)
755 {
756 if (m_iNativeAgentFails == 0)
757 PostEvent(EVENT_AGENT_FAIL, m_dwId, NULL);
758 m_iNativeAgentFails++;
759 }
0ba90743 760 SendPollerMsg(dwRqId, _T(" NetXMS native agent is not responding\r\n"));
364aa19a 761 }
f91fa4c2 762 delete pAgentConn;
364aa19a
VK
763
764 // Generate event if node flags has been changed
765 if (dwOldFlags != m_dwFlags)
6159a875 766 {
364aa19a 767 PostEvent(EVENT_NODE_FLAGS_CHANGED, m_dwId, "xx", dwOldFlags, m_dwFlags);
6159a875
VK
768 bHasChanges = TRUE;
769 }
364aa19a
VK
770
771 // Retrieve interface list
0ba90743
VK
772 SendPollerMsg(dwRqId, _T("Capability check finished\r\n"
773 "Checking interface configuration...\r\n"));
364aa19a
VK
774 pIfList = GetInterfaceList();
775 if (pIfList != NULL)
776 {
777 DWORD i;
323f8bec 778 int j;
364aa19a
VK
779
780 // Find non-existing interfaces
781 for(i = 0; i < m_dwChildCount; i++)
782 if (m_pChildList[i]->Type() == OBJECT_INTERFACE)
783 {
784 Interface *pInterface = (Interface *)m_pChildList[i];
364aa19a
VK
785
786 for(j = 0; j < pIfList->iNumEntries; j++)
787 if ((pIfList->pInterfaces[j].dwIndex == pInterface->IfIndex()) &&
788 (pIfList->pInterfaces[j].dwIpAddr == pInterface->IpAddr()) &&
789 (pIfList->pInterfaces[j].dwIpNetMask == pInterface->IpNetMask()))
790 break;
791 if (j == pIfList->iNumEntries)
792 {
793 // No such interface in current configuration, delete it
0ba90743
VK
794 SendPollerMsg(dwRqId, _T(" Interface \"%s\" is no longer exist\r\n"),
795 pInterface->Name());
364aa19a
VK
796 PostEvent(EVENT_INTERFACE_DELETED, m_dwId, "dsaa", pInterface->IfIndex(),
797 pInterface->Name(), pInterface->IpAddr(), pInterface->IpNetMask());
323f8bec 798 DeleteInterface(pInterface);
4e839863 799 i = 0xFFFFFFFF; // Restart loop
6159a875 800 bHasChanges = TRUE;
364aa19a
VK
801 }
802 }
803
b50f1100 804 // Add new interfaces and check configuration of existing
323f8bec
VK
805 for(j = 0; j < pIfList->iNumEntries; j++)
806 {
807 for(i = 0; i < m_dwChildCount; i++)
808 if (m_pChildList[i]->Type() == OBJECT_INTERFACE)
809 {
810 Interface *pInterface = (Interface *)m_pChildList[i];
811
812 if ((pIfList->pInterfaces[j].dwIndex == pInterface->IfIndex()) &&
813 (pIfList->pInterfaces[j].dwIpAddr == pInterface->IpAddr()) &&
814 (pIfList->pInterfaces[j].dwIpNetMask == pInterface->IpNetMask()))
b50f1100
VK
815 {
816 // Existing interface, check configuration
817 if (memcmp(pIfList->pInterfaces[j].bMacAddr, pInterface->MacAddr(), MAC_ADDR_LENGTH))
818 {
819 char szOldMac[16], szNewMac[16];
820
821 BinToStr((BYTE *)pInterface->MacAddr(), MAC_ADDR_LENGTH, szOldMac);
822 BinToStr(pIfList->pInterfaces[j].bMacAddr, MAC_ADDR_LENGTH, szNewMac);
28fbe2be 823 PostEvent(EVENT_MAC_ADDR_CHANGED, m_dwId, "idsss",
b50f1100
VK
824 pInterface->Id(), pInterface->IfIndex(),
825 pInterface->Name(), szOldMac, szNewMac);
826 pInterface->SetMacAddr(pIfList->pInterfaces[j].bMacAddr);
827 }
323f8bec 828 break;
b50f1100 829 }
323f8bec
VK
830 }
831 if (i == m_dwChildCount)
832 {
833 // New interface
0ba90743
VK
834 SendPollerMsg(dwRqId, _T(" Found new interface \"%s\"\r\n"),
835 pIfList->pInterfaces[j].szName);
323f8bec
VK
836 CreateNewInterface(pIfList->pInterfaces[j].dwIpAddr,
837 pIfList->pInterfaces[j].dwIpNetMask,
838 pIfList->pInterfaces[j].szName,
839 pIfList->pInterfaces[j].dwIndex,
b50f1100
VK
840 pIfList->pInterfaces[j].dwType,
841 pIfList->pInterfaces[j].bMacAddr);
6159a875 842 bHasChanges = TRUE;
323f8bec
VK
843 }
844 }
e0d3b217
VK
845
846 DestroyInterfaceList(pIfList);
364aa19a 847 }
e7b47627
VK
848 else
849 {
850 SendPollerMsg(dwRqId, _T(" Unable to get interface list from node\r\n"));
851 }
323f8bec 852
8bff53f6 853 m_tLastConfigurationPoll = time(NULL);
0ba90743
VK
854 SendPollerMsg(dwRqId, _T("Interface configuration check finished\r\n"
855 "Finished configuration poll for node %s\r\n"
856 "Node configuration was%schanged after poll\r\n"),
857 m_szName, bHasChanges ? _T(" ") : _T(" not "));
89235715
VK
858
859 // Finish configuration poll
4e839863 860 m_dwDynamicFlags &= ~NDF_QUEUED_FOR_CONFIG_POLL;
323f8bec 861 PollerUnlock();
b1dd534d 862 DbgPrintf(AF_DEBUG_DISCOVERY, "Finished configuration poll for node %s (ID: %d)", m_szName, m_dwId);
6159a875
VK
863
864 if (bHasChanges)
865 {
866 Lock();
867 Modify();
868 Unlock();
869 }
364aa19a 870}
6f595ce2
VK
871
872
1275c750
VK
873//
874// Connect to native agent
875//
876
877BOOL Node::ConnectToAgent(void)
878{
879 // Create new agent connection object if needed
880 if (m_pAgentConnection == NULL)
205acaf4 881 m_pAgentConnection = new AgentConnection(htonl(m_dwIpAddr), m_wAgentPort, m_wAuthMethod, m_szSharedSecret);
1275c750
VK
882
883 // Check if we already connected
884 if (m_pAgentConnection->Nop() == ERR_SUCCESS)
885 return TRUE;
886
887 // Close current connection or clean up after broken connection
888 m_pAgentConnection->Disconnect();
889 return m_pAgentConnection->Connect();
890}
891
892
893//
894// Get item's value via SNMP
895//
896
3ea35b38 897DWORD Node::GetItemFromSNMP(const char *szParam, DWORD dwBufSize, char *szBuffer)
1275c750 898{
80de4676
VK
899 DWORD dwResult;
900
901 dwResult = SnmpGet(m_iSNMPVersion, m_dwIpAddr, m_szCommunityString, szParam, NULL, 0,
902 szBuffer, dwBufSize, FALSE, TRUE);
903 return (dwResult == SNMP_ERR_SUCCESS) ? DCE_SUCCESS :
904 ((dwResult == SNMP_ERR_NO_OBJECT) ? DCE_NOT_SUPPORTED : DCE_COMM_ERROR);
1275c750
VK
905}
906
907
908//
909// Get item's value via native agent
910//
911
3ea35b38 912DWORD Node::GetItemFromAgent(const char *szParam, DWORD dwBufSize, char *szBuffer)
1275c750 913{
3ea35b38 914 DWORD dwError, dwResult = DCE_COMM_ERROR;
1275c750
VK
915 DWORD dwTries = 5;
916
3ea35b38
VK
917 AgentLock();
918
1275c750
VK
919 // Establish connection if needed
920 if (m_pAgentConnection == NULL)
921 if (!ConnectToAgent())
3ea35b38 922 goto end_loop;
1275c750
VK
923
924 // Get parameter from agent
925 while(dwTries-- > 0)
926 {
901c96c7 927 dwError = m_pAgentConnection->GetParameter((char *)szParam, dwBufSize, szBuffer);
1275c750
VK
928 switch(dwError)
929 {
930 case ERR_SUCCESS:
3ea35b38
VK
931 dwResult = DCE_SUCCESS;
932 goto end_loop;
1275c750 933 case ERR_UNKNOWN_PARAMETER:
3ea35b38
VK
934 dwResult = DCE_NOT_SUPPORTED;
935 goto end_loop;
1275c750
VK
936 case ERR_NOT_CONNECTED:
937 case ERR_CONNECTION_BROKEN:
938 if (!ConnectToAgent())
3ea35b38 939 goto end_loop;
1275c750
VK
940 break;
941 case ERR_REQUEST_TIMEOUT:
942 break;
943 }
944 }
3ea35b38
VK
945
946end_loop:
947 AgentUnlock();
948 return dwResult;
1275c750 949}
8e99117a
VK
950
951
952//
953// Get value for server's internal parameter
954//
955
3ea35b38 956DWORD Node::GetInternalItem(const char *szParam, DWORD dwBufSize, char *szBuffer)
8e99117a
VK
957{
958 DWORD dwError = DCE_SUCCESS;
959
960 if (!stricmp(szParam, "status"))
961 {
962 sprintf(szBuffer, "%d", m_iStatus);
963 }
0fd7132e
VK
964 else if (m_dwFlags & NF_IS_LOCAL_MGMT)
965 {
966 if (!stricmp(szParam, "Server.AverageDCPollerQueueSize"))
967 {
968 sprintf(szBuffer, "%f", g_dAvgPollerQueueSize);
969 }
970 else if (!stricmp(szParam, "Server.AverageDBWriterQueueSize"))
971 {
972 sprintf(szBuffer, "%f", g_dAvgDBWriterQueueSize);
973 }
4e839863
VK
974 else if (!stricmp(szParam, "Server.AverageStatusPollerQueueSize"))
975 {
976 sprintf(szBuffer, "%f", g_dAvgStatusPollerQueueSize);
977 }
978 else if (!stricmp(szParam, "Server.AverageConfigurationPollerQueueSize"))
979 {
980 sprintf(szBuffer, "%f", g_dAvgConfigPollerQueueSize);
981 }
982 else if (!stricmp(szParam, "Server.AverageDCIQueuingTime"))
983 {
984 sprintf(szBuffer, "%lu", g_dwAvgDCIQueuingTime);
985 }
0fd7132e
VK
986 else
987 {
988 dwError = DCE_NOT_SUPPORTED;
989 }
990 }
8e99117a
VK
991 else
992 {
993 dwError = DCE_NOT_SUPPORTED;
994 }
995
996 return dwError;
997}
129f8f7b
VK
998
999
80de4676
VK
1000//
1001// Get item's value for client
1002//
1003
1004DWORD Node::GetItemForClient(int iOrigin, const char *pszParam, char *pszBuffer, DWORD dwBufSize)
1005{
1006 DWORD dwResult = 0, dwRetCode;
1007
1008 // Get data from node
1009 switch(iOrigin)
1010 {
1011 case DS_INTERNAL:
1012 dwRetCode = GetInternalItem(pszParam, dwBufSize, pszBuffer);
1013 break;
1014 case DS_NATIVE_AGENT:
1015 dwRetCode = GetItemFromAgent(pszParam, dwBufSize, pszBuffer);
1016 break;
1017 case DS_SNMP_AGENT:
1018 dwRetCode = GetItemFromSNMP(pszParam, dwBufSize, pszBuffer);
1019 break;
1020 default:
1021 dwResult = RCC_INVALID_ARGUMENT;
1022 break;
1023 }
1024
1025 // Translate return code to RCC
1026 if (dwResult != RCC_INVALID_ARGUMENT)
1027 {
1028 switch(dwRetCode)
1029 {
1030 case DCE_SUCCESS:
1031 dwResult = RCC_SUCCESS;
1032 break;
1033 case DCE_COMM_ERROR:
1034 dwResult = RCC_COMM_FAILURE;
1035 break;
1036 case DCE_NOT_SUPPORTED:
1037 dwResult = RCC_DCI_NOT_SUPPORTED;
1038 break;
1039 default:
1040 dwResult = RCC_SYSTEM_FAILURE;
1041 break;
1042 }
1043 }
1044
1045 return dwResult;
1046}
1047
1048
129f8f7b
VK
1049//
1050// Put items which requires polling into the queue
1051//
1052
1053void Node::QueueItemsForPolling(Queue *pPollerQueue)
1054{
1055 DWORD i;
1056 time_t currTime;
1057
1058 currTime = time(NULL);
1059
1060 Lock();
1061 for(i = 0; i < m_dwNumItems; i++)
1062 {
3ea35b38 1063 if (m_ppItems[i]->ReadyForPolling(currTime))
129f8f7b 1064 {
3ea35b38 1065 m_ppItems[i]->SetBusyFlag(TRUE);
4e839863 1066 m_dwRefCount++; // Increment reference count for each queued DCI
5add75d8 1067 pPollerQueue->Put(m_ppItems[i]);
067f2689
VK
1068 }
1069 }
1070 Unlock();
1071}
1072
1073
b81249b7
VK
1074//
1075// Create CSCP message with object's data
1076//
1077
1078void Node::CreateMessage(CSCPMessage *pMsg)
1079{
70573ffe 1080 Template::CreateMessage(pMsg);
a5f8dbb8
VK
1081 pMsg->SetVariable(VID_FLAGS, m_dwFlags);
1082 pMsg->SetVariable(VID_DISCOVERY_FLAGS, m_dwDiscoveryFlags);
1083 pMsg->SetVariable(VID_AGENT_PORT, m_wAgentPort);
1084 pMsg->SetVariable(VID_AUTH_METHOD, m_wAuthMethod);
1085 pMsg->SetVariable(VID_SHARED_SECRET, m_szSharedSecret);
1086 pMsg->SetVariable(VID_COMMUNITY_STRING, m_szCommunityString);
1087 pMsg->SetVariable(VID_SNMP_OID, m_szObjectId);
18e26ff8 1088 pMsg->SetVariable(VID_NODE_TYPE, m_dwNodeType);
37c4d6aa 1089 pMsg->SetVariable(VID_SNMP_VERSION, (WORD)m_iSNMPVersion);
ae3a55d9 1090 pMsg->SetVariable(VID_AGENT_VERSION, m_szAgentVersion);
1c8b8363 1091 pMsg->SetVariable(VID_PLATFORM_NAME, m_szPlatformName);
b81249b7 1092}
24156e90
VK
1093
1094
1095//
1096// Modify object from message
1097//
1098
1099DWORD Node::ModifyFromMessage(CSCPMessage *pRequest, BOOL bAlreadyLocked)
1100{
1101 if (!bAlreadyLocked)
1102 Lock();
1103
1104 // Change listen port of native agent
1105 if (pRequest->IsVariableExist(VID_AGENT_PORT))
1106 m_wAgentPort = pRequest->GetVariableShort(VID_AGENT_PORT);
1107
1108 // Change authentication method of native agent
1109 if (pRequest->IsVariableExist(VID_AUTH_METHOD))
1110 m_wAuthMethod = pRequest->GetVariableShort(VID_AUTH_METHOD);
1111
1112 // Change shared secret of native agent
1113 if (pRequest->IsVariableExist(VID_SHARED_SECRET))
1114 pRequest->GetVariableStr(VID_SHARED_SECRET, m_szSharedSecret, MAX_SECRET_LENGTH);
1115
37c4d6aa
VK
1116 // Change SNMP protocol version
1117 if (pRequest->IsVariableExist(VID_SNMP_VERSION))
1118 m_iSNMPVersion = pRequest->GetVariableShort(VID_SNMP_VERSION);
1119
24156e90
VK
1120 // Change SNMP community string
1121 if (pRequest->IsVariableExist(VID_COMMUNITY_STRING))
1122 pRequest->GetVariableStr(VID_COMMUNITY_STRING, m_szCommunityString, MAX_COMMUNITY_LENGTH);
1123
70573ffe 1124 return Template::ModifyFromMessage(pRequest, TRUE);
24156e90 1125}
ed1140dc
VK
1126
1127
1128//
1129// Wakeup node using magic packet
1130//
1131
1132DWORD Node::WakeUp(void)
1133{
1134 DWORD i, dwResult = RCC_NO_WOL_INTERFACES;
1135
1136 Lock();
1137
1138 for(i = 0; i < m_dwChildCount; i++)
1139 if ((m_pChildList[i]->Type() == OBJECT_INTERFACE) &&
1140 (m_pChildList[i]->Status() != STATUS_UNMANAGED) &&
1141 (m_pChildList[i]->IpAddr() != 0))
1142 {
1143 dwResult = ((Interface *)m_pChildList[i])->WakeUp();
1144 break;
1145 }
1146
1147 Unlock();
1148 return dwResult;
1149}
80de4676
VK
1150
1151
1152//
1153// Get status of interface with given index from SNMP agent
1154//
1155
1156int Node::GetInterfaceStatusFromSNMP(DWORD dwIndex)
1157{
1158 return SnmpGetInterfaceStatus(m_dwIpAddr, m_iSNMPVersion, m_szCommunityString, dwIndex);
1159}
1160
1161
1162//
1163// Get status of interface with given index from native agent
1164//
1165
1166int Node::GetInterfaceStatusFromAgent(DWORD dwIndex)
1167{
1168 char szParam[128], szBuffer[32];
1169 DWORD dwAdminStatus, dwLinkState;
1170 int iStatus;
1171
1172 // Get administrative status
1173 sprintf(szParam, "Net.Interface.AdminStatus(%lu)", dwIndex);
1174 if (GetItemFromAgent(szParam, 32, szBuffer) == DCE_SUCCESS)
1175 {
1176 dwAdminStatus = strtoul(szBuffer, NULL, 0);
1177
1178 switch(dwAdminStatus)
1179 {
1180 case 3:
1181 iStatus = STATUS_TESTING;
1182 break;
1183 case 2:
1184 iStatus = STATUS_DISABLED;
1185 break;
1186 case 1: // Interface administratively up, check link state
1187 sprintf(szParam, "Net.Interface.Link(%lu)", dwIndex);
1188 if (GetItemFromAgent(szParam, 32, szBuffer) == DCE_SUCCESS)
1189 {
1190 dwLinkState = strtoul(szBuffer, NULL, 0);
1191 iStatus = (dwLinkState == 0) ? STATUS_CRITICAL : STATUS_NORMAL;
1192 }
1193 else
1194 {
1195 iStatus = STATUS_UNKNOWN;
1196 }
1197 default:
1198 iStatus = STATUS_UNKNOWN;
1199 break;
1200 }
1201 }
1202 else
1203 {
1204 iStatus = STATUS_UNKNOWN;
1205 }
1206
1207 return iStatus;
1208}
89235715
VK
1209
1210
1211//
1212// Put list of supported parameters into CSCP message
1213//
1214
1215void Node::WriteParamListToMessage(CSCPMessage *pMsg)
1216{
1217 DWORD i, dwId;
1218
1219 Lock();
1220 if (m_pParamList != NULL)
1221 {
1222 pMsg->SetVariable(VID_NUM_PARAMETERS, m_dwNumParams);
1223 for(i = 0, dwId = VID_PARAM_LIST_BASE; i < m_dwNumParams; i++)
1224 {
1225 pMsg->SetVariable(dwId++, m_pParamList[i].szName);
1226 pMsg->SetVariable(dwId++, m_pParamList[i].szDescription);
1227 pMsg->SetVariable(dwId++, (WORD)m_pParamList[i].iDataType);
1228 }
1229 }
1230 else
1231 {
1232 pMsg->SetVariable(VID_NUM_PARAMETERS, (DWORD)0);
1233 }
1234 Unlock();
1235}