new NXSL operator @
[public/netxms.git] / src / server / core / np.cpp
CommitLineData
5039dede
AK
1/*
2** NetXMS - Network Management System
496390c2 3** Copyright (C) 2003-2013 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: np.cpp
20**
21**/
22
23#include "nxcore.h"
24
56e92fc9
VK
25/**
26 * Externals
27 */
5039dede
AK
28extern Queue g_nodePollerQueue;
29
56e92fc9
VK
30/**
31 * Discovery class
32 */
5039dede
AK
33class NXSL_DiscoveryClass : public NXSL_Class
34{
35public:
36 NXSL_DiscoveryClass();
37
bb51576f 38 virtual NXSL_Value *getAttr(NXSL_Object *pObject, const TCHAR *pszAttr);
5039dede
AK
39};
40
56e92fc9
VK
41/**
42 * Implementation of discovery class
43 */
5039dede
AK
44NXSL_DiscoveryClass::NXSL_DiscoveryClass()
45 :NXSL_Class()
46{
35f836fe 47 _tcscpy(m_szName, _T("NewNode"));
5039dede
AK
48}
49
bb51576f 50NXSL_Value *NXSL_DiscoveryClass::getAttr(NXSL_Object *pObject, const TCHAR *pszAttr)
5039dede
AK
51{
52 DISCOVERY_FILTER_DATA *pData;
53 NXSL_Value *pValue = NULL;
35f836fe 54 TCHAR szBuffer[256];
5039dede 55
bb5365ed 56 pData = (DISCOVERY_FILTER_DATA *)pObject->getData();
35f836fe 57 if (!_tcscmp(pszAttr, _T("ipAddr")))
5039dede
AK
58 {
59 IpToStr(pData->dwIpAddr, szBuffer);
60 pValue = new NXSL_Value(szBuffer);
61 }
35f836fe 62 else if (!_tcscmp(pszAttr, _T("netMask")))
5039dede
AK
63 {
64 IpToStr(pData->dwNetMask, szBuffer);
65 pValue = new NXSL_Value(szBuffer);
66 }
35f836fe 67 else if (!_tcscmp(pszAttr, _T("subnet")))
5039dede
AK
68 {
69 IpToStr(pData->dwSubnetAddr, szBuffer);
70 pValue = new NXSL_Value(szBuffer);
71 }
35f836fe 72 else if (!_tcscmp(pszAttr, _T("isAgent")))
5039dede
AK
73 {
74 pValue = new NXSL_Value((LONG)((pData->dwFlags & NNF_IS_AGENT) ? 1 : 0));
75 }
35f836fe 76 else if (!_tcscmp(pszAttr, _T("isSNMP")))
5039dede
AK
77 {
78 pValue = new NXSL_Value((LONG)((pData->dwFlags & NNF_IS_SNMP) ? 1 : 0));
79 }
35f836fe 80 else if (!_tcscmp(pszAttr, _T("isBridge")))
5039dede
AK
81 {
82 pValue = new NXSL_Value((LONG)((pData->dwFlags & NNF_IS_BRIDGE) ? 1 : 0));
83 }
35f836fe 84 else if (!_tcscmp(pszAttr, _T("isRouter")))
5039dede
AK
85 {
86 pValue = new NXSL_Value((LONG)((pData->dwFlags & NNF_IS_ROUTER) ? 1 : 0));
87 }
35f836fe 88 else if (!_tcscmp(pszAttr, _T("isPrinter")))
5039dede
AK
89 {
90 pValue = new NXSL_Value((LONG)((pData->dwFlags & NNF_IS_PRINTER) ? 1 : 0));
91 }
35f836fe 92 else if (!_tcscmp(pszAttr, _T("isCDP")))
5039dede
AK
93 {
94 pValue = new NXSL_Value((LONG)((pData->dwFlags & NNF_IS_CDP) ? 1 : 0));
95 }
35f836fe 96 else if (!_tcscmp(pszAttr, _T("isSONMP")))
5039dede
AK
97 {
98 pValue = new NXSL_Value((LONG)((pData->dwFlags & NNF_IS_SONMP) ? 1 : 0));
99 }
35f836fe 100 else if (!_tcscmp(pszAttr, _T("isLLDP")))
5039dede
AK
101 {
102 pValue = new NXSL_Value((LONG)((pData->dwFlags & NNF_IS_LLDP) ? 1 : 0));
103 }
35f836fe 104 else if (!_tcscmp(pszAttr, _T("snmpVersion")))
5039dede
AK
105 {
106 pValue = new NXSL_Value((LONG)pData->nSNMPVersion);
107 }
35f836fe 108 else if (!_tcscmp(pszAttr, _T("snmpOID")))
5039dede
AK
109 {
110 pValue = new NXSL_Value(pData->szObjectId);
111 }
35f836fe 112 else if (!_tcscmp(pszAttr, _T("agentVersion")))
5039dede
AK
113 {
114 pValue = new NXSL_Value(pData->szAgentVersion);
115 }
35f836fe 116 else if (!_tcscmp(pszAttr, _T("platformName")))
5039dede
AK
117 {
118 pValue = new NXSL_Value(pData->szPlatform);
119 }
120 return pValue;
121}
122
22d657d2
VK
123/**
124 * Discovery class object
125 */
5039dede
AK
126static NXSL_DiscoveryClass m_nxslDiscoveryClass;
127
22d657d2
VK
128/**
129 * Poll new node for configuration
130 * Returns pointer to new node object on success or NULL on failure
131 *
132 * @param dwIpAddr IP address of new node
133 * @param dwNetMask IP network mask or 0 if not known
134 * @param dwCreationFlags
135 * @param agentPort port number of NetXMS agent
136 * @param snmpPort port number of SNMP agent
137 * @param pszName name for new node, can be NULL
138 * @param dwProxyNode agent proxy node ID or 0 to use direct communications
139 * @param dwSNMPProxy SNMP proxy node ID or 0 to use direct communications
140 * @param pCluster pointer to parent cluster object or NULL
141 * @param zoneId zone ID
142 * @param doConfPoll if set to true, Node::configurationPoll will be called before exit
143 * @param discoveredNode must be set to true if node being added automatically by discovery thread
144 */
07f6978d 145Node *PollNewNode(DWORD dwIpAddr, DWORD dwNetMask, DWORD dwCreationFlags,
ea12c2aa 146 WORD agentPort, WORD snmpPort, const TCHAR *pszName, DWORD dwProxyNode, DWORD dwSNMPProxy,
a749a70a 147 Cluster *pCluster, DWORD zoneId, bool doConfPoll, bool discoveredNode)
5039dede
AK
148{
149 Node *pNode;
35f836fe 150 TCHAR szIpAddr1[32], szIpAddr2[32];
5039dede
AK
151 DWORD dwFlags = 0;
152
dc25b21c 153 DbgPrintf(4, _T("PollNode(%s,%s) zone %d"), IpToStr(dwIpAddr, szIpAddr1), IpToStr(dwNetMask, szIpAddr2), (int)zoneId);
5039dede 154 // Check for node existence
89135050
VK
155 if ((FindNodeByIP(zoneId, dwIpAddr) != NULL) ||
156 (FindSubnetByIP(zoneId, dwIpAddr) != NULL))
5039dede 157 {
35f836fe 158 DbgPrintf(4, _T("PollNode: Node %s already exist in database"),
5039dede
AK
159 IpToStr(dwIpAddr, szIpAddr1));
160 return NULL;
161 }
162
163 if (dwCreationFlags & NXC_NCF_DISABLE_ICMP)
164 dwFlags |= NF_DISABLE_ICMP;
165 if (dwCreationFlags & NXC_NCF_DISABLE_SNMP)
166 dwFlags |= NF_DISABLE_SNMP;
167 if (dwCreationFlags & NXC_NCF_DISABLE_NXCP)
168 dwFlags |= NF_DISABLE_NXCP;
dc25b21c 169 pNode = new Node(dwIpAddr, dwFlags, dwProxyNode, dwSNMPProxy, zoneId);
f1b6417b
VK
170 if (agentPort != 0)
171 pNode->setAgentPort(agentPort);
172 if (snmpPort != 0)
173 pNode->setSnmpPort(snmpPort);
5039dede
AK
174 NetObjInsert(pNode, TRUE);
175 if (pszName != NULL)
eec253a8 176 pNode->setName(pszName);
5039dede 177
a749a70a
VK
178 // Use DNS name as primary name if required
179 if (discoveredNode && ConfigReadInt(_T("UseDNSNameForDiscoveredNodes"), 0))
180 {
181 DWORD ip = htonl(dwIpAddr);
182 struct hostent *hs = gethostbyaddr((char *)&ip, 4, AF_INET);
183 if (hs != NULL)
184 {
185 TCHAR dnsName[MAX_DNS_NAME];
186#ifdef UNICODE
187 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, hs->h_name, -1, dnsName, MAX_DNS_NAME);
188 dnsName[MAX_DNS_NAME - 1] = 0;
189#else
190 nx_strncpy(dnsName, hs->h_name, MAX_DNS_NAME);
191#endif
192 if (ntohl(ResolveHostName(dnsName)) == dwIpAddr)
193 {
194 // We have valid DNS name which resolves back to node's IP address, use it as primary name
195 pNode->setPrimaryName(dnsName);
196 DbgPrintf(4, _T("PollNode: Using DNS name %s as primary name for node %s"), dnsName, IpToStr(dwIpAddr, szIpAddr1));
197 }
198 }
199 }
200
5039dede
AK
201 // Bind node to cluster before first configuration poll
202 if (pCluster != NULL)
203 {
6fd6de0a 204 pCluster->applyToTarget(pNode);
5039dede
AK
205 }
206
207 if (dwCreationFlags & NXC_NCF_CREATE_UNMANAGED)
208 {
eec253a8 209 pNode->setMgmtStatus(FALSE);
5039dede 210 }
5039dede
AK
211
212 // Add default DCIs
f05a8a45
VK
213 pNode->addDCObject(new DCItem(CreateUniqueId(IDG_ITEM), _T("Status"), DS_INTERNAL, DCI_DT_INT,
214 ConfigReadInt(_T("DefaultDCIPollingInterval"), 60),
215 ConfigReadInt(_T("DefaultDCIRetentionTime"), 30), pNode));
588f7351
VK
216
217 if (doConfPoll)
218 pNode->configurationPoll(NULL, 0, -1, dwNetMask);
219
220 pNode->unhide();
221 PostEvent(EVENT_NODE_ADDED, pNode->Id(), NULL);
222
5039dede
AK
223 return pNode;
224}
225
22d657d2
VK
226/**
227 * Find existing node by MAC address to detect IP address change for already known node.
228 *
229 * @param dwIpAddr new (discovered) IP address
230 * @param dwNetMask network mask for new address
231 * @param dwZoneID zone ID
232 * @param bMacAddr MAC address of discovered node, or NULL if not known
233 *
234 * @return pointer to existing interface object with given MAC address or NULL if no such interface found
235 */
236static Interface *GetOldNodeWithNewIP(DWORD dwIpAddr, DWORD dwNetMask, DWORD dwZoneId, BYTE *bMacAddr)
baa5324c
AK
237{
238 Subnet *subnet;
239 BYTE nodeMacAddr[MAC_ADDR_LENGTH];
240 TCHAR szIpAddr[16], szMacAddr[20];
241
242 IpToStr(dwIpAddr, szIpAddr);
243 MACToStr(bMacAddr, szMacAddr);
244 DbgPrintf(6, _T("GetOldNodeWithNewIP: ip=%s mac=%s"), szIpAddr, szMacAddr);
245
246 if (bMacAddr == NULL)
247 {
9075806c 248 subnet = FindSubnetForNode(dwZoneId, dwIpAddr);
baa5324c
AK
249 if (subnet != NULL)
250 {
251 BOOL found = subnet->findMacAddress(dwIpAddr, nodeMacAddr);
252 if (!found)
253 {
22d657d2 254 DbgPrintf(6, _T("GetOldNodeWithNewIP: MAC address not found"));
baa5324c
AK
255 return NULL;
256 }
257 }
22d657d2
VK
258 else
259 {
260 DbgPrintf(6, _T("GetOldNodeWithNewIP: subnet not found"));
261 return NULL;
262 }
baa5324c
AK
263 }
264 else
265 {
266 memcpy(nodeMacAddr, bMacAddr, MAC_ADDR_LENGTH);
267 }
268
22d657d2 269 Interface *iface = FindInterfaceByMAC(nodeMacAddr);
baa5324c 270
22d657d2
VK
271 if (iface == NULL)
272 DbgPrintf(6, _T("GetOldNodeWithNewIP: returning null (FindInterfaceByMAC!)"));
baa5324c 273
22d657d2 274 return iface;
baa5324c 275}
5039dede 276
22d657d2
VK
277/**
278 * Check if newly discovered node should be added
279 */
baa5324c 280static BOOL AcceptNewNode(DWORD dwIpAddr, DWORD dwNetMask, DWORD zoneId, BYTE *macAddr)
5039dede
AK
281{
282 DISCOVERY_FILTER_DATA data;
df8a4ca2 283 TCHAR szFilter[MAX_DB_STRING], szBuffer[256], szIpAddr[16];
5039dede
AK
284 DWORD dwTemp;
285 AgentConnection *pAgentConn;
286 NXSL_Program *pScript;
287 NXSL_Value *pValue;
288 BOOL bResult = FALSE;
289 SNMP_UDPTransport *pTransport;
290
291 IpToStr(dwIpAddr, szIpAddr);
89135050
VK
292 if ((FindNodeByIP(zoneId, dwIpAddr) != NULL) ||
293 (FindSubnetByIP(zoneId, dwIpAddr) != NULL))
5039dede 294 {
35f836fe 295 DbgPrintf(4, _T("AcceptNewNode(%s): node already exist in database"), szIpAddr);
5039dede
AK
296 return FALSE; // Node already exist in database
297 }
298
22d657d2
VK
299 Interface *iface = GetOldNodeWithNewIP(dwIpAddr, dwNetMask, zoneId, macAddr);
300 if (iface != NULL)
baa5324c 301 {
22d657d2
VK
302 Node *oldNode = iface->getParentNode();
303 if (iface->IpAddr() == oldNode->IpAddr())
304 {
305 // we should change node's primary IP only if old IP for this MAC was also node's primary IP
306 TCHAR szOldIpAddr[16];
307 IpToStr(oldNode->IpAddr(), szOldIpAddr);
308 DbgPrintf(4, _T("AcceptNewNode(%s): node already exist in database with ip %s, will change to new"),
309 szIpAddr, szOldIpAddr);
310 oldNode->changeIPAddress(dwIpAddr);
311 }
baa5324c
AK
312 return FALSE;
313 }
314
496390c2
VK
315 // Allow filtering by loaded modules
316 for(DWORD i = 0; i < g_dwNumModules; i++)
317 {
318 if (g_pModuleList[i].pfAcceptNewNode != NULL)
319 {
320 if (!g_pModuleList[i].pfAcceptNewNode(dwIpAddr, dwNetMask, zoneId, macAddr))
321 return FALSE; // filtered out by module
322 }
323 }
324
5039dede 325 // Read configuration
35f836fe 326 ConfigReadStr(_T("DiscoveryFilter"), szFilter, MAX_DB_STRING, _T(""));
5039dede
AK
327 StrStrip(szFilter);
328
56e92fc9 329 // Check for filter script
35f836fe 330 if ((szFilter[0] == 0) || (!_tcsicmp(szFilter, _T("none"))))
5039dede 331 {
35f836fe 332 DbgPrintf(4, _T("AcceptNewNode(%s): no filtering, node accepted"), szIpAddr);
5039dede
AK
333 return TRUE; // No filtering
334 }
335
336 // Initialize new node data
337 memset(&data, 0, sizeof(DISCOVERY_FILTER_DATA));
338 data.dwIpAddr = dwIpAddr;
339 data.dwNetMask = dwNetMask;
340 data.dwSubnetAddr = dwIpAddr & dwNetMask;
341
56e92fc9
VK
342 // Check for address range if we use simple filter instead of script
343 DWORD autoFilterFlags;
344 if (!_tcsicmp(szFilter, _T("auto")))
345 {
346 autoFilterFlags = ConfigReadULong(_T("DiscoveryFilterFlags"), DFF_ALLOW_AGENT | DFF_ALLOW_SNMP);
347 DbgPrintf(4, _T("AcceptNewNode(%s): auto filter, flags=%04X"), szIpAddr, autoFilterFlags);
348
349 if (autoFilterFlags & DFF_ONLY_RANGE)
350 {
351 DbgPrintf(4, _T("AcceptNewNode(%s): auto filter - checking range"), szIpAddr);
352 DB_RESULT hResult = DBSelect(g_hCoreDB, _T("SELECT addr_type,addr1,addr2 FROM address_lists WHERE list_type=2"));
353 if (hResult != NULL)
354 {
355 int nRows = DBGetNumRows(hResult);
356 for(int i = 0; (i < nRows) && (!bResult); i++)
357 {
358 int nType = DBGetFieldLong(hResult, i, 0);
359 if (nType == 0)
360 {
361 // Subnet
362 bResult = (data.dwIpAddr & DBGetFieldIPAddr(hResult, i, 2)) == DBGetFieldIPAddr(hResult, i, 1);
363 }
364 else
365 {
366 // Range
367 bResult = ((data.dwIpAddr >= DBGetFieldIPAddr(hResult, i, 1)) &&
368 (data.dwIpAddr <= DBGetFieldIPAddr(hResult, i, 2)));
369 }
370 }
371 DBFreeResult(hResult);
372 }
3b71dbbb
VK
373 DbgPrintf(4, _T("AcceptNewNode(%s): auto filter - range check result is %d"), szIpAddr, bResult);
374 if (!bResult)
375 return FALSE;
56e92fc9 376 }
56e92fc9
VK
377 }
378
5039dede 379 // Check SNMP support
35f836fe 380 DbgPrintf(4, _T("AcceptNewNode(%s): checking SNMP support"), szIpAddr);
5039dede 381 pTransport = new SNMP_UDPTransport;
c4366266 382 pTransport->createUDPTransport(NULL, htonl(dwIpAddr), 161);
df8a4ca2
VK
383 SNMP_SecurityContext *ctx = SnmpCheckCommSettings(pTransport, &data.nSNMPVersion, NULL);
384 if (ctx != NULL)
5039dede
AK
385 {
386 data.dwFlags |= NNF_IS_SNMP;
df8a4ca2 387 delete ctx;
5039dede
AK
388 }
389
390 // Check NetXMS agent support
35f836fe 391 DbgPrintf(4, _T("AcceptNewNode(%s): checking NetXMS agent"), szIpAddr);
5039dede 392 pAgentConn = new AgentConnection(htonl(dwIpAddr), AGENT_LISTEN_PORT,
35f836fe 393 AUTH_NONE, _T(""));
7c521895 394 if (pAgentConn->connect(g_pServerKey))
5039dede
AK
395 {
396 data.dwFlags |= NNF_IS_AGENT;
4687826e
VK
397 pAgentConn->getParameter(_T("Agent.Version"), MAX_AGENT_VERSION_LEN, data.szAgentVersion);
398 pAgentConn->getParameter(_T("System.PlatformName"), MAX_PLATFORM_NAME_LEN, data.szPlatform);
5039dede
AK
399 }
400
401 // Check if node is a router
402 if (data.dwFlags & NNF_IS_SNMP)
403 {
5d2c5741 404 if (SnmpGet(data.nSNMPVersion, pTransport,
f42b8099 405 _T(".1.3.6.1.2.1.4.1.0"), NULL, 0, &dwTemp, sizeof(DWORD), 0) == SNMP_ERR_SUCCESS)
5039dede
AK
406 {
407 if (dwTemp == 1)
408 data.dwFlags |= NNF_IS_ROUTER;
409 }
410 }
411 else if (data.dwFlags & NNF_IS_AGENT)
412 {
413 // Check IP forwarding status
4687826e 414 if (pAgentConn->getParameter(_T("Net.IP.Forwarding"), 16, szBuffer) == ERR_SUCCESS)
5039dede
AK
415 {
416 if (_tcstoul(szBuffer, NULL, 10) != 0)
417 data.dwFlags |= NNF_IS_ROUTER;
418 }
419 }
420
421 // Check various SNMP device capabilities
422 if (data.dwFlags & NNF_IS_SNMP)
423 {
424 // Get SNMP OID
5d2c5741 425 SnmpGet(data.nSNMPVersion, pTransport,
f42b8099 426 _T(".1.3.6.1.2.1.1.2.0"), NULL, 0, data.szObjectId, MAX_OID_LEN * 4, 0);
5039dede
AK
427
428 // Check if node is a bridge
5d2c5741 429 if (SnmpGet(data.nSNMPVersion, pTransport,
f42b8099 430 _T(".1.3.6.1.2.1.17.1.1.0"), NULL, 0, szBuffer, 256, 0) == SNMP_ERR_SUCCESS)
5039dede
AK
431 {
432 data.dwFlags |= NNF_IS_BRIDGE;
433 }
434
435 // Check for CDP (Cisco Discovery Protocol) support
5d2c5741 436 if (SnmpGet(data.nSNMPVersion, pTransport,
f42b8099 437 _T(".1.3.6.1.4.1.9.9.23.1.3.1.0"), NULL, 0, &dwTemp, sizeof(DWORD), 0) == SNMP_ERR_SUCCESS)
5039dede
AK
438 {
439 if (dwTemp == 1)
440 data.dwFlags |= NNF_IS_CDP;
441 }
442
443 // Check for SONMP (Nortel topology discovery protocol) support
5d2c5741 444 if (SnmpGet(data.nSNMPVersion, pTransport,
f42b8099 445 _T(".1.3.6.1.4.1.45.1.6.13.1.2.0"), NULL, 0, &dwTemp, sizeof(DWORD), 0) == SNMP_ERR_SUCCESS)
5039dede
AK
446 {
447 if (dwTemp == 1)
448 data.dwFlags |= NNF_IS_SONMP;
449 }
450
451 // Check for LLDP (Link Layer Discovery Protocol) support
5d2c5741 452 if (SnmpGet(data.nSNMPVersion, pTransport,
f42b8099 453 _T(".1.0.8802.1.1.2.1.3.2.0"), NULL, 0, szBuffer, 256, 0) == SNMP_ERR_SUCCESS)
5039dede
AK
454 {
455 data.dwFlags |= NNF_IS_LLDP;
456 }
457 }
458
459 // Cleanup
460 delete pAgentConn;
461 delete pTransport;
462
463 // Check if we use simple filter instead of script
35f836fe 464 if (!_tcsicmp(szFilter, _T("auto")))
5039dede 465 {
56e92fc9
VK
466 bResult = FALSE;
467 if ((autoFilterFlags & (DFF_ALLOW_AGENT | DFF_ALLOW_SNMP)) == 0)
5039dede
AK
468 {
469 bResult = TRUE;
470 }
471 else
472 {
56e92fc9 473 if (autoFilterFlags & DFF_ALLOW_AGENT)
5039dede
AK
474 {
475 if (data.dwFlags & NNF_IS_AGENT)
476 bResult = TRUE;
477 }
478
56e92fc9 479 if (autoFilterFlags & DFF_ALLOW_SNMP)
5039dede
AK
480 {
481 if (data.dwFlags & NNF_IS_SNMP)
482 bResult = TRUE;
483 }
484 }
35f836fe 485 DbgPrintf(4, _T("AcceptNewNode(%s): auto filter - bResult=%d"), szIpAddr, bResult);
5039dede
AK
486 }
487 else
488 {
bb5365ed
VK
489 g_pScriptLibrary->lock();
490 pScript = g_pScriptLibrary->findScript(szFilter);
5039dede
AK
491 if (pScript != NULL)
492 {
35f836fe 493 DbgPrintf(4, _T("AcceptNewNode(%s): Running filter script %s"), szIpAddr, szFilter);
5039dede 494 pValue = new NXSL_Value(new NXSL_Object(&m_nxslDiscoveryClass, &data));
13ceb0fb 495 if (pScript->run(new NXSL_ServerEnv, 1, &pValue) == 0)
5039dede 496 {
bb5365ed 497 bResult = (pScript->getResult()->getValueAsInt32() != 0) ? TRUE : FALSE;
35f836fe 498 DbgPrintf(4, _T("AcceptNewNode(%s): Filter script result: %d"), szIpAddr, bResult);
5039dede
AK
499 }
500 else
501 {
35f836fe 502 DbgPrintf(4, _T("AcceptNewNode(%s): Filter script execution error: %s"),
bb5365ed 503 szIpAddr, pScript->getErrorText());
35f836fe 504 PostEvent(EVENT_SCRIPT_ERROR, g_dwMgmtNode, "ssd", szFilter,
bb5365ed 505 pScript->getErrorText(), 0);
5039dede
AK
506 }
507 }
508 else
509 {
35f836fe 510 DbgPrintf(4, _T("AcceptNewNode(%s): Cannot find filter script %s"), szIpAddr, szFilter);
5039dede 511 }
bb5365ed 512 g_pScriptLibrary->unlock();
5039dede
AK
513 }
514
515 return bResult;
516}
517
496390c2
VK
518/**
519 * Node poller thread (poll new nodes and put them into the database)
520 */
5039dede
AK
521THREAD_RESULT THREAD_CALL NodePoller(void *arg)
522{
523 NEW_NODE *pInfo;
524 TCHAR szIpAddr[16], szNetMask[16];
525
35f836fe 526 DbgPrintf(1, _T("Node poller started"));
5039dede 527
89135050 528 while(!IsShutdownInProgress())
5039dede
AK
529 {
530 pInfo = (NEW_NODE *)g_nodePollerQueue.GetOrBlock();
531 if (pInfo == INVALID_POINTER_VALUE)
532 break; // Shutdown indicator received
533
dc25b21c
VK
534 DbgPrintf(4, _T("NodePoller: processing node %s/%s in zone %d"),
535 IpToStr(pInfo->dwIpAddr, szIpAddr), IpToStr(pInfo->dwNetMask, szNetMask), (int)pInfo->zoneId);
baa5324c 536 if (AcceptNewNode(pInfo->dwIpAddr, pInfo->dwNetMask, pInfo->zoneId, pInfo->bMacAddr))
07f6978d 537 {
f1b6417b 538 Node *node = PollNewNode(pInfo->dwIpAddr, pInfo->dwNetMask, 0, 0, 0, NULL, 0, 0, NULL, pInfo->zoneId, true, true);
07f6978d 539 }
5039dede
AK
540 free(pInfo);
541 }
35f836fe 542 DbgPrintf(1, _T("Node poller thread terminated"));
5039dede
AK
543 return THREAD_OK;
544}