2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003-2017 Victor Kirhenshtein
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 extern Queue g_nodePollerQueue
;
33 class NXSL_DiscoveryClass
: public NXSL_Class
36 NXSL_DiscoveryClass();
38 virtual NXSL_Value
*getAttr(NXSL_Object
*pObject
, const TCHAR
*pszAttr
);
42 * Implementation of discovery class
44 NXSL_DiscoveryClass
::NXSL_DiscoveryClass() : NXSL_Class()
46 setName(_T("NewNode"));
49 NXSL_Value
*NXSL_DiscoveryClass
::getAttr(NXSL_Object
*pObject
, const TCHAR
*pszAttr
)
51 DISCOVERY_FILTER_DATA
*pData
;
52 NXSL_Value
*pValue
= NULL
;
55 pData
= (DISCOVERY_FILTER_DATA
*)pObject
->getData();
56 if (!_tcscmp(pszAttr
, _T("ipAddr")))
58 pValue
= new NXSL_Value(pData
->ipAddr
.toString(szBuffer
));
60 else if (!_tcscmp(pszAttr
, _T("netMask")))
62 pValue
= new NXSL_Value(pData
->ipAddr
.getMaskBits());
64 else if (!_tcscmp(pszAttr
, _T("subnet")))
66 pValue
= new NXSL_Value(pData
->ipAddr
.getSubnetAddress().toString(szBuffer
));
68 else if (!_tcscmp(pszAttr
, _T("isAgent")))
70 pValue
= new NXSL_Value((LONG
)((pData
->dwFlags
& NNF_IS_AGENT
) ?
1 : 0));
72 else if (!_tcscmp(pszAttr
, _T("isSNMP")))
74 pValue
= new NXSL_Value((LONG
)((pData
->dwFlags
& NNF_IS_SNMP
) ?
1 : 0));
76 else if (!_tcscmp(pszAttr
, _T("isBridge")))
78 pValue
= new NXSL_Value((LONG
)((pData
->dwFlags
& NNF_IS_BRIDGE
) ?
1 : 0));
80 else if (!_tcscmp(pszAttr
, _T("isRouter")))
82 pValue
= new NXSL_Value((LONG
)((pData
->dwFlags
& NNF_IS_ROUTER
) ?
1 : 0));
84 else if (!_tcscmp(pszAttr
, _T("isPrinter")))
86 pValue
= new NXSL_Value((LONG
)((pData
->dwFlags
& NNF_IS_PRINTER
) ?
1 : 0));
88 else if (!_tcscmp(pszAttr
, _T("isCDP")))
90 pValue
= new NXSL_Value((LONG
)((pData
->dwFlags
& NNF_IS_CDP
) ?
1 : 0));
92 else if (!_tcscmp(pszAttr
, _T("isSONMP")))
94 pValue
= new NXSL_Value((LONG
)((pData
->dwFlags
& NNF_IS_SONMP
) ?
1 : 0));
96 else if (!_tcscmp(pszAttr
, _T("isLLDP")))
98 pValue
= new NXSL_Value((LONG
)((pData
->dwFlags
& NNF_IS_LLDP
) ?
1 : 0));
100 else if (!_tcscmp(pszAttr
, _T("snmpVersion")))
102 pValue
= new NXSL_Value((LONG
)pData
->nSNMPVersion
);
104 else if (!_tcscmp(pszAttr
, _T("snmpOID")))
106 pValue
= new NXSL_Value(pData
->szObjectId
);
108 else if (!_tcscmp(pszAttr
, _T("agentVersion")))
110 pValue
= new NXSL_Value(pData
->szAgentVersion
);
112 else if (!_tcscmp(pszAttr
, _T("platformName")))
114 pValue
= new NXSL_Value(pData
->szPlatform
);
120 * Discovery class object
122 static NXSL_DiscoveryClass m_nxslDiscoveryClass
;
125 * Poll new node for configuration
126 * Returns pointer to new node object on success or NULL on failure
128 * @param ipAddr IP address of new node
129 * @param creationFlags node creation flags
130 * @param agentPort port number of NetXMS agent
131 * @param snmpPort port number of SNMP agent
132 * @param name name for new node, can be NULL
133 * @param agentProxyId agent proxy node ID or 0 to use direct communications
134 * @param snmpProxyId SNMP proxy node ID or 0 to use direct communications
135 * @param icmpProxyId ICMP proxy node ID or 0 to use direct communications
136 * @param sshProxyId SSH proxy node ID or 0 to use default proxy
137 * @param sshLogin SSH login name
138 * @param sshPassword SSH password
139 * @param cluster pointer to parent cluster object or NULL
140 * @param zoneUIN zone ID
141 * @param doConfPoll if set to true, Node::configurationPoll will be called before exit
142 * @param discoveredNode must be set to true if node being added automatically by discovery thread
144 Node NXCORE_EXPORTABLE
*PollNewNode(const InetAddress
& ipAddr
, UINT32 creationFlags
, UINT16 agentPort
,
145 UINT16 snmpPort
, const TCHAR
*name
, UINT32 agentProxyId
, UINT32 snmpProxyId
,
146 UINT32 icmpProxyId
, UINT32 sshProxyId
, const TCHAR
*sshLogin
, const TCHAR
*sshPassword
,
147 Cluster
*cluster
, UINT32 zoneUIN
, bool doConfPoll
, bool discoveredNode
)
153 DbgPrintf(4, _T("PollNode(%s/%d) zone %d"), ipAddr
.toString(szIpAddr
), ipAddr
.getMaskBits(), (int)zoneUIN
);
154 // Check for node existence
155 if ((FindNodeByIP(zoneUIN
, ipAddr
) != NULL
) ||
156 (FindSubnetByIP(zoneUIN
, ipAddr
) != NULL
))
158 DbgPrintf(4, _T("PollNode: Node %s already exist in database"), szIpAddr
);
162 if (creationFlags
& NXC_NCF_DISABLE_ICMP
)
163 dwFlags
|= NF_DISABLE_ICMP
;
164 if (creationFlags
& NXC_NCF_DISABLE_SNMP
)
165 dwFlags
|= NF_DISABLE_SNMP
;
166 if (creationFlags
& NXC_NCF_DISABLE_NXCP
)
167 dwFlags
|= NF_DISABLE_NXCP
;
168 pNode
= new Node(ipAddr
, dwFlags
, 0, agentProxyId
, snmpProxyId
, icmpProxyId
, sshProxyId
, zoneUIN
);
170 pNode
->setAgentPort(agentPort
);
172 pNode
->setSnmpPort(snmpPort
);
173 pNode
->setSshCredentials(sshLogin
, sshPassword
);
175 pNode
->setName(name
);
176 NetObjInsert(pNode
, true, false);
178 // Use DNS name as primary name if required
179 if (discoveredNode
&& ConfigReadInt(_T("UseDNSNameForDiscoveredNodes"), 0))
181 TCHAR dnsName
[MAX_DNS_NAME
];
183 if(IsZoningEnabled() && zoneUIN
!= 0)
185 AgentConnectionEx
*conn
= pNode
->getConnectionToZoneNodeProxy();
186 tmp
= conn
!= NULL ? conn
->getHostByAddr(ipAddr
, dnsName
, MAX_DNS_NAME
) : NULL
;
190 tmp
= ipAddr
.getHostByAddr(dnsName
, MAX_DNS_NAME
);
195 if(ResolveHostName(zoneUIN
, dnsName
).equals(ipAddr
))
197 // We have valid DNS name which resolves back to node's IP address, use it as primary name
198 pNode
->setPrimaryName(dnsName
);
199 DbgPrintf(4, _T("PollNode: Using DNS name %s as primary name for node %s"), dnsName
, szIpAddr
);
204 // Bind node to cluster before first configuration poll
207 cluster
->applyToTarget(pNode
);
210 if (creationFlags
& NXC_NCF_CREATE_UNMANAGED
)
212 pNode
->setMgmtStatus(FALSE
);
213 pNode
->checkSubnetBinding();
218 pNode
->configurationPollWorkerEntry(RegisterPoller(POLLER_TYPE_CONFIGURATION
, pNode
));
222 PostEvent(EVENT_NODE_ADDED
, pNode
->getId(), "d", (int)(discoveredNode ?
1 : 0));
228 * Find existing node by MAC address to detect IP address change for already known node.
230 * @param ipAddr new (discovered) IP address
231 * @param zoneUIN zone ID
232 * @param bMacAddr MAC address of discovered node, or NULL if not known
234 * @return pointer to existing interface object with given MAC address or NULL if no such interface found
236 static Interface
*GetOldNodeWithNewIP(const InetAddress
& ipAddr
, UINT32 zoneUIN
, BYTE
*bMacAddr
)
239 BYTE nodeMacAddr
[MAC_ADDR_LENGTH
];
240 TCHAR szIpAddr
[64], szMacAddr
[20];
242 ipAddr
.toString(szIpAddr
);
243 MACToStr(bMacAddr
, szMacAddr
);
244 DbgPrintf(6, _T("GetOldNodeWithNewIP: ip=%s mac=%s"), szIpAddr
, szMacAddr
);
246 if (bMacAddr
== NULL
)
248 subnet
= FindSubnetForNode(zoneUIN
, ipAddr
);
251 BOOL found
= subnet
->findMacAddress(ipAddr
, nodeMacAddr
);
254 DbgPrintf(6, _T("GetOldNodeWithNewIP: MAC address not found"));
260 DbgPrintf(6, _T("GetOldNodeWithNewIP: subnet not found"));
266 memcpy(nodeMacAddr
, bMacAddr
, MAC_ADDR_LENGTH
);
269 Interface
*iface
= FindInterfaceByMAC(nodeMacAddr
);
272 DbgPrintf(6, _T("GetOldNodeWithNewIP: returning null (FindInterfaceByMAC!)"));
278 * Check if host at given IP address is reachable by NetXMS server
280 static bool HostIsReachable(const InetAddress
& ipAddr
, UINT32 zoneUIN
, bool fullCheck
, SNMP_Transport
**transport
, AgentConnection
**agentConn
)
282 bool reachable
= false;
284 if (transport
!= NULL
)
286 if (agentConn
!= NULL
)
289 UINT32 agentProxy
= 0;
290 UINT32 icmpProxy
= 0;
291 UINT32 snmpProxy
= 0;
293 if (IsZoningEnabled() && (zoneUIN
!= 0))
295 Zone
*zone
= FindZoneByUIN(zoneUIN
);
298 agentProxy
= zone
->getProxyNodeId();
299 icmpProxy
= zone
->getProxyNodeId();
300 snmpProxy
= zone
->getProxyNodeId();
307 Node
*proxyNode
= (Node
*)g_idxNodeById
.get(icmpProxy
);
308 if ((proxyNode
!= NULL
) && proxyNode
->isNativeAgent() && !proxyNode
->isDown())
310 AgentConnection
*conn
= proxyNode
->createAgentConnection();
313 TCHAR parameter
[128], buffer
[64];
315 _sntprintf(parameter
, 128, _T("Icmp.Ping(%s)"), ipAddr
.toString(buffer
));
316 if (conn
->getParameter(parameter
, 64, buffer
) == ERR_SUCCESS
)
319 long value
= _tcstol(buffer
, &eptr
, 10);
320 if ((*eptr
== 0) && (value
>= 0))
332 else // not using ICMP proxy
334 if (IcmpPing(ipAddr
, 3, g_icmpPingTimeout
, NULL
, g_icmpPingSize
) == ICMP_SUCCESS
)
338 if (reachable
&& !fullCheck
)
341 // *** NetXMS agent ***
342 AgentConnection
*pAgentConn
= new AgentConnectionEx(0, ipAddr
, AGENT_LISTEN_PORT
, AUTH_NONE
, _T(""));
345 Node
*proxyNode
= (Node
*)g_idxNodeById
.get(agentProxy
);
346 if (proxyNode
!= NULL
)
348 pAgentConn
->setProxy(proxyNode
->getIpAddress(), proxyNode
->getAgentPort(),
349 proxyNode
->getAgentAuthMethod(), proxyNode
->getSharedSecret());
352 pAgentConn
->setCommandTimeout(g_agentCommandTimeout
);
354 if (!pAgentConn
->connect(g_pServerKey
, &rcc
))
356 // If there are authentication problem, try default shared secret
357 if ((rcc
== ERR_AUTH_REQUIRED
) || (rcc
== ERR_AUTH_FAILED
))
359 TCHAR secret
[MAX_SECRET_LENGTH
];
360 ConfigReadStr(_T("AgentDefaultSharedSecret"), secret
, MAX_SECRET_LENGTH
, _T("netxms"));
361 DecryptPassword(_T("netxms"), secret
, secret
, MAX_SECRET_LENGTH
);
363 pAgentConn
->setAuthData(AUTH_SHA1_HASH
, secret
);
364 pAgentConn
->connect(g_pServerKey
, &rcc
);
367 if (rcc
== ERR_SUCCESS
)
369 if (agentConn
!= NULL
)
371 *agentConn
= pAgentConn
;
372 pAgentConn
= NULL
; // prevent deletion
376 if (pAgentConn
!= NULL
)
377 pAgentConn
->decRefCount();
379 if (reachable
&& !fullCheck
)
385 oids
.add(_T(".1.3.6.1.2.1.1.2.0"));
386 oids
.add(_T(".1.3.6.1.2.1.1.1.0"));
387 AddDriverSpecificOids(&oids
);
388 SNMP_Transport
*pTransport
= SnmpCheckCommSettings(snmpProxy
, ipAddr
, &version
, 0, NULL
, &oids
);
390 if (pTransport
!= NULL
)
392 if (transport
!= NULL
)
394 pTransport
->setSnmpVersion(version
);
395 *transport
= pTransport
;
396 pTransport
= NULL
; // prevent deletion
406 * Check if newly discovered node should be added
408 static BOOL
AcceptNewNode(const InetAddress
& addr
, UINT32 zoneUIN
, BYTE
*macAddr
)
410 DISCOVERY_FILTER_DATA data
;
411 TCHAR szFilter
[MAX_CONFIG_VALUE
], szBuffer
[256], szIpAddr
[64];
413 AgentConnection
*pAgentConn
;
414 BOOL bResult
= FALSE
;
415 SNMP_Transport
*pTransport
;
417 addr
.toString(szIpAddr
);
418 if ((FindNodeByIP(zoneUIN
, addr
) != NULL
) ||
419 (FindSubnetByIP(zoneUIN
, addr
) != NULL
))
421 DbgPrintf(4, _T("AcceptNewNode(%s): node already exist in database"), szIpAddr
);
422 return FALSE
; // Node already exist in database
425 if (!memcmp(macAddr
, "\xFF\xFF\xFF\xFF\xFF\xFF", 6))
427 DbgPrintf(4, _T("AcceptNewNode(%s): broadcast MAC address"), szIpAddr
);
428 return FALSE
; // Broadcast MAC
431 NXSL_VM
*hook
= FindHookScript(_T("AcceptNewNode"));
435 hook
->setGlobalVariable(_T("$ipAddr"), new NXSL_Value(szIpAddr
));
436 hook
->setGlobalVariable(_T("$ipNetMask"), new NXSL_Value(addr
.getMaskBits()));
437 MACToStr(macAddr
, szBuffer
);
438 hook
->setGlobalVariable(_T("$macAddr"), new NXSL_Value(szBuffer
));
439 hook
->setGlobalVariable(_T("$zoneUIN"), new NXSL_Value(zoneUIN
));
442 NXSL_Value
*result
= hook
->getResult();
443 if (result
->isZero())
446 DbgPrintf(4, _T("AcceptNewNode(%s): rejected by hook script"), szIpAddr
);
451 DbgPrintf(4, _T("AcceptNewNode(%s): hook script execution error: %s"), szIpAddr
, hook
->getErrorText());
455 return FALSE
; // blocked by hook
458 Interface
*iface
= GetOldNodeWithNewIP(addr
, zoneUIN
, macAddr
);
461 if (!HostIsReachable(addr
, zoneUIN
, false, NULL
, NULL
))
463 DbgPrintf(4, _T("AcceptNewNode(%s): found existing interface with same MAC address, but new IP is not reachable"), szIpAddr
);
467 Node
*oldNode
= iface
->getParentNode();
468 if (iface
->getIpAddressList()->hasAddress(oldNode
->getIpAddress()))
470 // we should change node's primary IP only if old IP for this MAC was also node's primary IP
471 TCHAR szOldIpAddr
[16];
472 oldNode
->getIpAddress().toString(szOldIpAddr
);
473 DbgPrintf(4, _T("AcceptNewNode(%s): node already exist in database with ip %s, will change to new"), szIpAddr
, szOldIpAddr
);
474 oldNode
->changeIPAddress(addr
);
479 // Allow filtering by loaded modules
480 for(UINT32 i
= 0; i
< g_dwNumModules
; i
++)
482 if (g_pModuleList
[i
].pfAcceptNewNode
!= NULL
)
484 if (!g_pModuleList
[i
].pfAcceptNewNode(addr
, zoneUIN
, macAddr
))
485 return FALSE
; // filtered out by module
489 // Read configuration
490 ConfigReadStr(_T("DiscoveryFilter"), szFilter
, MAX_CONFIG_VALUE
, _T(""));
493 // Check for filter script
494 if ((szFilter
[0] == 0) || (!_tcsicmp(szFilter
, _T("none"))))
496 if (!HostIsReachable(addr
, zoneUIN
, false, NULL
, NULL
))
498 DbgPrintf(4, _T("AcceptNewNode(%s): host is not reachable"), szIpAddr
);
501 DbgPrintf(4, _T("AcceptNewNode(%s): no filtering, node accepted"), szIpAddr
);
502 return TRUE
; // No filtering
505 // Initialize new node data
506 memset(&data
, 0, sizeof(DISCOVERY_FILTER_DATA
));
509 // Check for address range if we use simple filter instead of script
510 UINT32 autoFilterFlags
;
511 if (!_tcsicmp(szFilter
, _T("auto")))
513 autoFilterFlags
= ConfigReadULong(_T("DiscoveryFilterFlags"), DFF_ALLOW_AGENT
| DFF_ALLOW_SNMP
);
514 DbgPrintf(4, _T("AcceptNewNode(%s): auto filter, flags=%04X"), szIpAddr
, autoFilterFlags
);
516 if (autoFilterFlags
& DFF_ONLY_RANGE
)
518 DbgPrintf(4, _T("AcceptNewNode(%s): auto filter - checking range"), szIpAddr
);
519 DB_HANDLE hdb
= DBConnectionPoolAcquireConnection();
520 DB_RESULT hResult
= DBSelect(hdb
, _T("SELECT addr_type,addr1,addr2 FROM address_lists WHERE list_type=2"));
523 int nRows
= DBGetNumRows(hResult
);
524 for(int i
= 0; (i
< nRows
) && (!bResult
); i
++)
526 bResult
= InetAddressListElement(hResult
, i
).contains(data
.ipAddr
);
528 DBFreeResult(hResult
);
530 DBConnectionPoolReleaseConnection(hdb
);
531 DbgPrintf(4, _T("AcceptNewNode(%s): auto filter - range check result is %d"), szIpAddr
, bResult
);
537 // Check if host is reachable
538 if (!HostIsReachable(addr
, zoneUIN
, true, &pTransport
, &pAgentConn
))
540 DbgPrintf(4, _T("AcceptNewNode(%s): host is not reachable"), szIpAddr
);
543 if (pTransport
!= NULL
)
545 data
.dwFlags
|= NNF_IS_SNMP
;
546 data
.nSNMPVersion
= pTransport
->getSnmpVersion();
548 if (pAgentConn
!= NULL
)
550 data
.dwFlags
|= NNF_IS_AGENT
;
551 pAgentConn
->getParameter(_T("Agent.Version"), MAX_AGENT_VERSION_LEN
, data
.szAgentVersion
);
552 pAgentConn
->getParameter(_T("System.PlatformName"), MAX_PLATFORM_NAME_LEN
, data
.szPlatform
);
555 // Check if node is a router
556 if (data
.dwFlags
& NNF_IS_SNMP
)
558 if (SnmpGet(data
.nSNMPVersion
, pTransport
,
559 _T(".1.3.6.1.2.1.4.1.0"), NULL
, 0, &dwTemp
, sizeof(UINT32
), 0) == SNMP_ERR_SUCCESS
)
562 data
.dwFlags
|= NNF_IS_ROUTER
;
565 else if (data
.dwFlags
& NNF_IS_AGENT
)
567 // Check IP forwarding status
568 if (pAgentConn
->getParameter(_T("Net.IP.Forwarding"), 16, szBuffer
) == ERR_SUCCESS
)
570 if (_tcstoul(szBuffer
, NULL
, 10) != 0)
571 data
.dwFlags
|= NNF_IS_ROUTER
;
575 // Check various SNMP device capabilities
576 if (data
.dwFlags
& NNF_IS_SNMP
)
579 SnmpGet(data
.nSNMPVersion
, pTransport
,
580 _T(".1.3.6.1.2.1.1.2.0"), NULL
, 0, data
.szObjectId
, MAX_OID_LEN
* 4, 0);
582 // Check if node is a bridge
583 if (SnmpGet(data
.nSNMPVersion
, pTransport
,
584 _T(".1.3.6.1.2.1.17.1.1.0"), NULL
, 0, szBuffer
, sizeof(szBuffer
), 0) == SNMP_ERR_SUCCESS
)
586 data
.dwFlags
|= NNF_IS_BRIDGE
;
589 // Check for CDP (Cisco Discovery Protocol) support
590 if (SnmpGet(data
.nSNMPVersion
, pTransport
,
591 _T(".1.3.6.1.4.1.9.9.23.1.3.1.0"), NULL
, 0, &dwTemp
, sizeof(UINT32
), 0) == SNMP_ERR_SUCCESS
)
594 data
.dwFlags
|= NNF_IS_CDP
;
597 // Check for SONMP (Nortel topology discovery protocol) support
598 if (SnmpGet(data
.nSNMPVersion
, pTransport
,
599 _T(".1.3.6.1.4.1.45.1.6.13.1.2.0"), NULL
, 0, &dwTemp
, sizeof(UINT32
), 0) == SNMP_ERR_SUCCESS
)
602 data
.dwFlags
|= NNF_IS_SONMP
;
605 // Check for LLDP (Link Layer Discovery Protocol) support
606 if (SnmpGet(data
.nSNMPVersion
, pTransport
,
607 _T(".1.0.8802.1.1.2.1.3.2.0"), NULL
, 0, szBuffer
, sizeof(szBuffer
), 0) == SNMP_ERR_SUCCESS
)
609 data
.dwFlags
|= NNF_IS_LLDP
;
614 if (pAgentConn
!= NULL
)
615 pAgentConn
->decRefCount();
618 // Check if we use simple filter instead of script
619 if (!_tcsicmp(szFilter
, _T("auto")))
622 if ((autoFilterFlags
& (DFF_ALLOW_AGENT
| DFF_ALLOW_SNMP
)) == 0)
628 if (autoFilterFlags
& DFF_ALLOW_AGENT
)
630 if (data
.dwFlags
& NNF_IS_AGENT
)
634 if (autoFilterFlags
& DFF_ALLOW_SNMP
)
636 if (data
.dwFlags
& NNF_IS_SNMP
)
640 DbgPrintf(4, _T("AcceptNewNode(%s): auto filter - bResult=%d"), szIpAddr
, bResult
);
644 NXSL_VM
*vm
= CreateServerScriptVM(szFilter
);
647 DbgPrintf(4, _T("AcceptNewNode(%s): Running filter script %s"), szIpAddr
, szFilter
);
648 NXSL_Value
*pValue
= new NXSL_Value(new NXSL_Object(&m_nxslDiscoveryClass
, &data
));
649 if (vm
->run(1, &pValue
))
651 bResult
= (vm
->getResult()->getValueAsInt32() != 0) ? TRUE
: FALSE
;
652 DbgPrintf(4, _T("AcceptNewNode(%s): Filter script result: %d"), szIpAddr
, bResult
);
656 DbgPrintf(4, _T("AcceptNewNode(%s): Filter script execution error: %s"),
657 szIpAddr
, vm
->getErrorText());
658 PostEvent(EVENT_SCRIPT_ERROR
, g_dwMgmtNode
, "ssd", szFilter
, vm
->getErrorText(), 0);
664 DbgPrintf(4, _T("AcceptNewNode(%s): Cannot find filter script %s"), szIpAddr
, szFilter
);
672 * Node poller thread (poll new nodes and put them into the database)
674 THREAD_RESULT THREAD_CALL
NodePoller(void *arg
)
679 ThreadSetName("NodePoller");
680 nxlog_debug(1, _T("Node poller started"));
682 while(!IsShutdownInProgress())
684 pInfo
= (NEW_NODE
*)g_nodePollerQueue
.getOrBlock();
685 if (pInfo
== INVALID_POINTER_VALUE
)
686 break; // Shutdown indicator received
688 DbgPrintf(4, _T("NodePoller: processing node %s/%d in zone %d"),
689 pInfo
->ipAddr
.toString(szIpAddr
), pInfo
->ipAddr
.getMaskBits(), (int)pInfo
->zoneUIN
);
690 if (pInfo
->ignoreFilter
|| AcceptNewNode(pInfo
->ipAddr
, pInfo
->zoneUIN
, pInfo
->bMacAddr
))
692 ObjectTransactionStart();
693 PollNewNode(pInfo
->ipAddr
, 0, 0, 0, NULL
, 0, 0, 0, 0, NULL
, NULL
, NULL
, pInfo
->zoneUIN
, true, true);
694 ObjectTransactionEnd();
698 nxlog_debug(1, _T("Node poller thread terminated"));