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