code refactoring; preparation for zoning support
[public/netxms.git] / src / server / core / subnet.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003, 2004 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: subnet.cpp
20 **
21 **/
22
23 #include "nxcore.h"
24
25
26 //
27 // Subnet class default constructor
28 //
29
30 Subnet::Subnet()
31 :NetObj()
32 {
33 m_dwIpNetMask = 0;
34 m_zoneId = 0;
35 m_bSyntheticMask = false;
36 }
37
38
39 //
40 // Subnet class constructor
41 //
42
43 Subnet::Subnet(DWORD dwAddr, DWORD dwNetMask, DWORD dwZone, bool bSyntheticMask)
44 {
45 TCHAR szBuffer[32];
46
47 m_dwIpAddr = dwAddr;
48 m_dwIpNetMask = dwNetMask;
49 _sntprintf(m_szName, MAX_OBJECT_NAME, _T("%s/%d"), IpToStr(dwAddr, szBuffer), BitsInMask(dwNetMask));
50 m_zoneId = dwZone;
51 m_bSyntheticMask = bSyntheticMask;
52 }
53
54
55 //
56 // Subnet class destructor
57 //
58
59 Subnet::~Subnet()
60 {
61 }
62
63
64 //
65 // Create object from database data
66 //
67
68 BOOL Subnet::CreateFromDB(DWORD dwId)
69 {
70 TCHAR szQuery[256];
71 DB_RESULT hResult;
72
73 m_dwId = dwId;
74
75 if (!LoadCommonProperties())
76 return FALSE;
77
78 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("SELECT ip_addr,ip_netmask,zone_guid,synthetic_mask FROM subnets WHERE id=%d"), dwId);
79 hResult = DBSelect(g_hCoreDB, szQuery);
80 if (hResult == 0)
81 return FALSE; // Query failed
82
83 if (DBGetNumRows(hResult) == 0)
84 {
85 DBFreeResult(hResult);
86 return FALSE;
87 }
88
89 m_dwIpAddr = DBGetFieldIPAddr(hResult, 0, 0);
90 m_dwIpNetMask = DBGetFieldIPAddr(hResult, 0, 1);
91 m_zoneId = DBGetFieldULong(hResult, 0, 2);
92 m_bSyntheticMask = DBGetFieldLong(hResult, 0, 3) ? true : false;
93
94 DBFreeResult(hResult);
95
96 // Load access list
97 LoadACLFromDB();
98
99 return TRUE;
100 }
101
102
103 //
104 // Save subnet object to database
105 //
106
107 BOOL Subnet::SaveToDB(DB_HANDLE hdb)
108 {
109 TCHAR szQuery[1024], szIpAddr[16], szNetMask[16];
110 DB_RESULT hResult;
111 DWORD i;
112 BOOL bNewObject = TRUE;
113
114 // Lock object's access
115 LockData();
116
117 SaveCommonProperties(hdb);
118
119 // Check for object's existence in database
120 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("SELECT id FROM subnets WHERE id=%d"), m_dwId);
121 hResult = DBSelect(hdb, szQuery);
122 if (hResult != 0)
123 {
124 if (DBGetNumRows(hResult) > 0)
125 bNewObject = FALSE;
126 DBFreeResult(hResult);
127 }
128
129 // Form and execute INSERT or UPDATE query
130 if (bNewObject)
131 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR),
132 _T("INSERT INTO subnets (id,ip_addr,ip_netmask,zone_guid,synthetic_mask) VALUES (%d,'%s','%s',%d,%d)"),
133 m_dwId, IpToStr(m_dwIpAddr, szIpAddr),
134 IpToStr(m_dwIpNetMask, szNetMask), m_zoneId, m_bSyntheticMask ? 1 : 0);
135 else
136 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR),
137 _T("UPDATE subnets SET ip_addr='%s',ip_netmask='%s',zone_guid=%d,synthetic_mask=%d WHERE id=%d"),
138 IpToStr(m_dwIpAddr, szIpAddr),
139 IpToStr(m_dwIpNetMask, szNetMask), m_zoneId, m_bSyntheticMask ? 1 : 0, m_dwId);
140 DBQuery(hdb, szQuery);
141
142 // Update node to subnet mapping
143 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("DELETE FROM nsmap WHERE subnet_id=%d"), m_dwId);
144 DBQuery(hdb, szQuery);
145 LockChildList(FALSE);
146 for(i = 0; i < m_dwChildCount; i++)
147 {
148 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("INSERT INTO nsmap (subnet_id,node_id) VALUES (%d,%d)"), m_dwId, m_pChildList[i]->Id());
149 DBQuery(hdb, szQuery);
150 }
151 UnlockChildList();
152
153 // Save access list
154 SaveACLToDB(hdb);
155
156 // Clear modifications flag and unlock object
157 m_bIsModified = FALSE;
158 UnlockData();
159
160 return TRUE;
161 }
162
163
164 //
165 // Delete subnet object from database
166 //
167
168 BOOL Subnet::DeleteFromDB(void)
169 {
170 TCHAR szQuery[256];
171 BOOL bSuccess;
172
173 bSuccess = NetObj::DeleteFromDB();
174 if (bSuccess)
175 {
176 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("DELETE FROM subnets WHERE id=%d"), m_dwId);
177 QueueSQLRequest(szQuery);
178 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("DELETE FROM nsmap WHERE subnet_id=%d"), m_dwId);
179 QueueSQLRequest(szQuery);
180 }
181 return bSuccess;
182 }
183
184
185 //
186 // Create CSCP message with object's data
187 //
188
189 void Subnet::CreateMessage(CSCPMessage *pMsg)
190 {
191 NetObj::CreateMessage(pMsg);
192 pMsg->SetVariable(VID_IP_NETMASK, m_dwIpNetMask);
193 pMsg->SetVariable(VID_ZONE_ID, m_zoneId);
194 pMsg->SetVariable(VID_SYNTHETIC_MASK, (WORD)(m_bSyntheticMask ? 1 : 0));
195 }
196
197
198 //
199 // Set correct netmask for subnet
200 //
201
202 void Subnet::setCorrectMask(DWORD dwAddr, DWORD dwMask)
203 {
204 TCHAR szName[128], szBuffer[32];
205
206 LockData();
207
208 // Check if name is default
209 _sntprintf(szName, 128, _T("%s/%d"), IpToStr(m_dwIpAddr, szBuffer), BitsInMask(m_dwIpNetMask));
210 if (!_tcsicmp(szName, m_szName))
211 {
212 // Change name
213 _sntprintf(m_szName, 128, _T("%s/%d"), IpToStr(dwAddr, szBuffer), BitsInMask(dwMask));
214 }
215
216 m_dwIpAddr = dwAddr;
217 m_dwIpNetMask = dwMask;
218 m_bSyntheticMask = false;
219
220 Modify();
221 UnlockData();
222 }