Fixed incorrect data type constants usage; confusing DT_xxx and DTYPE_xxx constants...
[public/netxms.git] / src / server / core / discovery.cpp
1 /*
2 ** Project X - Network Management System
3 ** Copyright (C) 2003 Victor Kirhenshtein
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: discovery.cpp
20 **
21 **/
22
23 #include "nms_core.h"
24
25
26 //
27 // Check if management server node presented in node list
28 //
29
30 void CheckForMgmtNode(void)
31 {
32 INTERFACE_LIST *pIfList;
33 Node *pNode;
34 int i;
35
36 pIfList = GetLocalInterfaceList();
37 if (pIfList != NULL)
38 {
39 for(i = 0; i < pIfList->iNumEntries; i++)
40 if ((pNode = FindNodeByIP(pIfList->pInterfaces[i].dwIpAddr)) != NULL)
41 {
42 g_dwMgmtNode = pNode->Id(); // Set local management node ID
43 break;
44 }
45 if (i == pIfList->iNumEntries) // No such node
46 {
47 // Find interface with IP address
48 for(i = 0; i < pIfList->iNumEntries; i++)
49 if (pIfList->pInterfaces[i].dwIpAddr != 0)
50 {
51 pNode = new Node(pIfList->pInterfaces[i].dwIpAddr, NF_IS_LOCAL_MGMT, DF_DEFAULT);
52 NetObjInsert(pNode, TRUE);
53 if (!pNode->NewNodePoll(0))
54 {
55 ObjectsGlobalLock();
56 NetObjDelete(pNode);
57 ObjectsGlobalUnlock();
58 delete pNode; // Node poll failed, delete it
59 }
60 else
61 {
62 g_dwMgmtNode = pNode->Id(); // Set local management node ID
63 /* DEBUG */
64 pNode->AddItem(new DCItem(CreateUniqueId(IDG_ITEM), "Status", DS_INTERNAL, DCI_DT_INTEGER, 60, 30, pNode));
65 }
66 break;
67 }
68 }
69 DestroyInterfaceList(pIfList);
70 }
71 }
72
73
74 //
75 // Network discovery thread
76 //
77
78 void DiscoveryThread(void *arg)
79 {
80 DWORD dwNewNodeId = 1, dwWatchdogId;
81 Node *pNode;
82
83 dwWatchdogId = WatchdogAddThread("Network Discovery Thread");
84
85 // Flush new nodes table
86 DBQuery(g_hCoreDB, "DELETE FROM new_nodes");
87
88 while(!ShutdownInProgress())
89 {
90 if (SleepAndCheckForShutdown(30))
91 break; // Shutdown has arrived
92 WatchdogNotify(dwWatchdogId);
93
94 CheckForMgmtNode();
95
96 // Walk through nodes and poll for ARP tables
97 MutexLock(g_hMutexNodeIndex, INFINITE);
98 for(DWORD i = 0; i < g_dwNodeAddrIndexSize; i++)
99 {
100 pNode = (Node *)g_pNodeIndexByAddr[i].pObject;
101 if (pNode->ReadyForDiscoveryPoll())
102 {
103 ARP_CACHE *pArpCache;
104
105 // Retrieve and analize node's ARP cache
106 pArpCache = pNode->GetArpCache();
107 if (pArpCache != NULL)
108 {
109 for(DWORD j = 0; j < pArpCache->dwNumEntries; j++)
110 {
111 if (FindNodeByIP(pArpCache->pEntries[j].dwIpAddr) == NULL)
112 {
113 Interface *pInterface = pNode->FindInterface(pArpCache->pEntries[j].dwIndex,
114 pArpCache->pEntries[j].dwIpAddr);
115 if (pInterface != NULL)
116 if (!IsBroadcastAddress(pArpCache->pEntries[j].dwIpAddr,
117 pInterface->IpNetMask()))
118 {
119 char szQuery[256];
120
121 sprintf(szQuery, "INSERT INTO new_nodes (id,ip_addr,ip_netmask,discovery_flags) VALUES (%d,%d,%d,%d)",
122 dwNewNodeId++, pArpCache->pEntries[j].dwIpAddr,
123 pInterface->IpNetMask(), DF_DEFAULT);
124 DBQuery(g_hCoreDB, szQuery);
125 }
126 }
127 }
128 DestroyArpCache(pArpCache);
129 }
130
131 pNode->SetDiscoveryPollTimeStamp();
132 }
133 }
134 MutexUnlock(g_hMutexNodeIndex);
135 }
136 }