cec069dc1ed0bc710674d88bcb7490af0d3e62aa
[public/netxms.git] / src / agent / core / getparam.cpp
1 /*
2 ** NetXMS multiplatform core agent
3 ** Copyright (C) 2003-2016 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 ** File: getparam.cpp
20 **
21 **/
22
23 #include "nxagentd.h"
24
25 #if defined(_WIN32)
26 #include <intrin.h>
27 #elif HAVE_CPUID_H
28 #include <cpuid.h>
29 #endif
30
31 /**
32 * Parameter handlers
33 */
34 LONG H_ActionList(const TCHAR *cmd, const TCHAR *arg, StringList *value, AbstractCommSession *session);
35 LONG H_ActiveConnections(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
36 LONG H_AgentProxyStats(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
37 LONG H_AgentTraps(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
38 LONG H_AgentUptime(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
39 LONG H_CRC32(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
40 LONG H_DataCollectorQueueSize(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
41 LONG H_DirInfo(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
42 LONG H_ExternalParameter(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
43 LONG H_ExternalList(const TCHAR *cmd, const TCHAR *arg, StringList *value, AbstractCommSession *session);
44 LONG H_ExternalTable(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractCommSession *session);
45 LONG H_FileTime(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
46 LONG H_HostName(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
47 LONG H_IsExtSubagentConnected(const TCHAR *pszCmd, const TCHAR *pArg, TCHAR *pValue, AbstractCommSession *session);
48 LONG H_IsSubagentLoaded(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
49 LONG H_MD5Hash(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
50 LONG H_PlatformName(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
51 LONG H_ResolverAddrByName(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
52 LONG H_ResolverNameByAddr(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
53 LONG H_SessionAgents(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractCommSession *session);
54 LONG H_SHA1Hash(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
55 LONG H_SNMPProxyStats(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
56 LONG H_SubAgentList(const TCHAR *cmd, const TCHAR *arg, StringList *value, AbstractCommSession *session);
57 LONG H_SubAgentTable(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractCommSession *session);
58 LONG H_SyslogStats(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
59 LONG H_SystemTime(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
60 LONG H_ThreadPoolInfo(const TCHAR *param, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
61 LONG H_ThreadPoolList(const TCHAR *param, const TCHAR *arg, StringList *value, AbstractCommSession *session);
62
63 #ifdef _WIN32
64 LONG H_CPUCount(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
65 LONG H_DiskInfo(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
66 LONG H_FileSystems(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractCommSession *session);
67 LONG H_FileSystemType(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
68 LONG H_MemoryInfo(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
69 LONG H_MountPoints(const TCHAR *cmd, const TCHAR *arg, StringList *value, AbstractCommSession *session);
70 LONG H_PhysicalDiskInfo(const TCHAR *cmd, const TCHAR *arg, TCHAR *pValue, AbstractCommSession *session);
71 LONG H_SystemUname(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
72 #endif
73
74 /**
75 * Static data
76 */
77 static NETXMS_SUBAGENT_PARAM *m_pParamList = NULL;
78 static int m_iNumParams = 0;
79 static NETXMS_SUBAGENT_PUSHPARAM *m_pPushParamList = NULL;
80 static int m_iNumPushParams = 0;
81 static NETXMS_SUBAGENT_LIST *m_pEnumList = NULL;
82 static int m_iNumEnums = 0;
83 static NETXMS_SUBAGENT_TABLE *m_pTableList = NULL;
84 static int m_iNumTables = 0;
85 static UINT32 m_dwTimedOutRequests = 0;
86 static UINT32 m_dwAuthenticationFailures = 0;
87 static UINT32 m_dwProcessedRequests = 0;
88 static UINT32 m_dwFailedRequests = 0;
89 static UINT32 m_dwUnsupportedRequests = 0;
90
91 /**
92 * Handler for parameters which always returns string constant
93 */
94 static LONG H_StringConstant(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session)
95 {
96 ret_string(value, arg);
97 return SYSINFO_RC_SUCCESS;
98 }
99
100 /**
101 * Handler for parameters which returns UINT32 value from specific variable
102 */
103 static LONG H_UIntPtr(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session)
104 {
105 ret_uint(value, *((UINT32 *)arg));
106 return SYSINFO_RC_SUCCESS;
107 }
108
109 /**
110 * Handler for Agent.SupportedCiphers
111 */
112 static LONG H_SupportedCiphers(const TCHAR *pszCmd, const TCHAR *pArg, TCHAR *pValue, AbstractCommSession *session)
113 {
114 UINT32 dwCiphers;
115
116 dwCiphers = NXCPGetSupportedCiphers();
117 if (dwCiphers == 0)
118 {
119 ret_string(pValue, _T("NONE"));
120 }
121 else
122 {
123 *pValue = 0;
124 if (dwCiphers & NXCP_SUPPORT_AES_256)
125 _tcscat(pValue, _T("AES-256 "));
126 if (dwCiphers & NXCP_SUPPORT_AES_128)
127 _tcscat(pValue, _T("AES-128 "));
128 if (dwCiphers & NXCP_SUPPORT_BLOWFISH_256)
129 _tcscat(pValue, _T("BF-256 "));
130 if (dwCiphers & NXCP_SUPPORT_BLOWFISH_128)
131 _tcscat(pValue, _T("BF-128 "));
132 if (dwCiphers & NXCP_SUPPORT_IDEA)
133 _tcscat(pValue, _T("IDEA "));
134 if (dwCiphers & NXCP_SUPPORT_3DES)
135 _tcscat(pValue, _T("3DES "));
136 pValue[_tcslen(pValue) - 1] = 0;
137 }
138 return SYSINFO_RC_SUCCESS;
139 }
140
141 /**
142 * Handler for parameters list
143 */
144 static LONG H_ParamList(const TCHAR *cmd, const TCHAR *arg, StringList *value, AbstractCommSession *session)
145 {
146 int i;
147
148 for(i = 0; i < m_iNumParams; i++)
149 if (m_pParamList[i].dataType != DCI_DT_DEPRECATED)
150 value->add(m_pParamList[i].name);
151 ListParametersFromExtProviders(value);
152 ListParametersFromExtSubagents(value);
153 return SYSINFO_RC_SUCCESS;
154 }
155
156 /**
157 * Handler for push parameters list
158 */
159 static LONG H_PushParamList(const TCHAR *cmd, const TCHAR *arg, StringList *value, AbstractCommSession *session)
160 {
161 int i;
162
163 for(i = 0; i < m_iNumPushParams; i++)
164 value->add(m_pPushParamList[i].name);
165 return SYSINFO_RC_SUCCESS;
166 }
167
168 /**
169 * Handler for enums list
170 */
171 static LONG H_EnumList(const TCHAR *cmd, const TCHAR *arg, StringList *value, AbstractCommSession *session)
172 {
173 int i;
174
175 for(i = 0; i < m_iNumEnums; i++)
176 value->add(m_pEnumList[i].name);
177 ListListsFromExtSubagents(value);
178 return SYSINFO_RC_SUCCESS;
179 }
180
181 /**
182 * Handler for table list
183 */
184 static LONG H_TableList(const TCHAR *cmd, const TCHAR *arg, StringList *value, AbstractCommSession *session)
185 {
186 int i;
187
188 for(i = 0; i < m_iNumTables; i++)
189 value->add(m_pTableList[i].name);
190 ListTablesFromExtSubagents(value);
191 return SYSINFO_RC_SUCCESS;
192 }
193
194 /**
195 * Handler for component statuses based on failure flags
196 */
197 static LONG H_ComponentStatus(const TCHAR *pszParam, const TCHAR *pArg, TCHAR *pValue, AbstractCommSession *session)
198 {
199 UINT32 result = 0;
200 switch(*pArg)
201 {
202 case 'D':
203 if ((g_failFlags & FAIL_OPEN_DATABASE) != 0)
204 result++;
205 if ((g_failFlags & FAIL_UPGRADE_DATABASE) != 0)
206 result++;
207 break;
208 case 'L':
209 if ((g_failFlags & FAIL_OPEN_LOG) != 0)
210 result++;
211 break;
212 }
213
214 ret_uint(pValue, result);
215 return SYSINFO_RC_SUCCESS;
216 }
217
218 /**
219 * Handler for local database counters
220 */
221 static LONG H_LocalDatabaseCounters(const TCHAR *pszParam, const TCHAR *pArg, TCHAR *pValue, AbstractCommSession *session)
222 {
223 LIBNXDB_PERF_COUNTERS counters;
224 DBGetPerfCounters(&counters);
225 switch(*pArg)
226 {
227 case 'F':
228 ret_int64(pValue, counters.failedQueries);
229 break;
230 case 'L':
231 ret_int64(pValue, counters.longRunningQueries);
232 break;
233 case 'T':
234 ret_int64(pValue, counters.totalQueries);
235 break;
236 default:
237 return SYSINFO_RC_UNSUPPORTED;
238 }
239 return SYSINFO_RC_SUCCESS;
240 }
241
242 /**
243 * Handler for flag query parameters
244 */
245 static LONG H_FlagValue(const TCHAR *param, const TCHAR *arg, TCHAR *value, AbstractCommSession *session)
246 {
247 UINT32 flag = CAST_FROM_POINTER(arg, UINT32);
248 ret_int(value, (g_dwFlags & flag) ? 1 : 0);
249 return SYSINFO_RC_SUCCESS;
250 }
251
252 #if HAVE_GET_CPUID
253
254 /**
255 * Handler for System.IsVirtual parameter
256 */
257 static LONG H_SystemIsVirtual(const TCHAR *param, const TCHAR *arg, TCHAR *value, AbstractCommSession *session)
258 {
259 unsigned int eax, ebx, ecx, edx;
260 if (__get_cpuid(0x1, &eax, &ebx, &ecx, &edx) != 1)
261 return SYSINFO_RC_UNSUPPORTED;
262 ret_int(value, (ecx & 0x80000000) != 0 ? 1 : 0);
263 return SYSINFO_RC_SUCCESS;
264 }
265
266 #elif defined(_WIN32)
267
268 /**
269 * Handler for System.IsVirtual parameter
270 */
271 static LONG H_SystemIsVirtual(const TCHAR *param, const TCHAR *arg, TCHAR *value, AbstractCommSession *session)
272 {
273 int data[4];
274 __cpuid(data, 0x01);
275 ret_int(value, (data[2] & 0x80000000) != 0 ? 1 : 0);
276 return SYSINFO_RC_SUCCESS;
277 }
278
279 #endif
280
281
282 /**
283 * Standard agent's parameters
284 */
285 static NETXMS_SUBAGENT_PARAM m_stdParams[] =
286 {
287 #ifdef _WIN32
288 { _T("Disk.Free(*)"), H_DiskInfo, (TCHAR *)DISKINFO_FREE_BYTES, DCI_DT_DEPRECATED, DCIDESC_DEPRECATED },
289 { _T("Disk.FreePerc(*)"), H_DiskInfo, (TCHAR *)DISKINFO_FREE_SPACE_PCT, DCI_DT_DEPRECATED, DCIDESC_DEPRECATED },
290 { _T("Disk.Total(*)"), H_DiskInfo, (TCHAR *)DISKINFO_TOTAL_BYTES, DCI_DT_DEPRECATED, DCIDESC_DEPRECATED },
291 { _T("Disk.Used(*)"), H_DiskInfo, (TCHAR *)DISKINFO_USED_BYTES, DCI_DT_DEPRECATED, DCIDESC_DEPRECATED },
292 { _T("Disk.UsedPerc(*)"), H_DiskInfo, (TCHAR *)DISKINFO_USED_SPACE_PCT, DCI_DT_DEPRECATED, DCIDESC_DEPRECATED },
293 { _T("FileSystem.Free(*)"), H_DiskInfo, (TCHAR *)DISKINFO_FREE_BYTES, DCI_DT_UINT64, DCIDESC_FS_FREE },
294 { _T("FileSystem.FreePerc(*)"), H_DiskInfo, (TCHAR *)DISKINFO_FREE_SPACE_PCT, DCI_DT_FLOAT, DCIDESC_FS_FREEPERC },
295 { _T("FileSystem.Total(*)"), H_DiskInfo, (TCHAR *)DISKINFO_TOTAL_BYTES, DCI_DT_UINT64, DCIDESC_FS_TOTAL },
296 { _T("FileSystem.Type(*)"), H_FileSystemType, NULL, DCI_DT_STRING, DCIDESC_FS_TYPE },
297 { _T("FileSystem.Used(*)"), H_DiskInfo, (TCHAR *)DISKINFO_USED_BYTES, DCI_DT_UINT64, DCIDESC_FS_USED },
298 { _T("FileSystem.UsedPerc(*)"), H_DiskInfo, (TCHAR *)DISKINFO_USED_SPACE_PCT, DCI_DT_FLOAT, DCIDESC_FS_USEDPERC },
299 { _T("PhysicalDisk.Firmware(*)"), H_PhysicalDiskInfo, _T("F"), DCI_DT_STRING, DCIDESC_PHYSICALDISK_FIRMWARE },
300 { _T("PhysicalDisk.Model(*)"), H_PhysicalDiskInfo, _T("M"), DCI_DT_STRING, DCIDESC_PHYSICALDISK_MODEL },
301 { _T("PhysicalDisk.SerialNumber(*)"), H_PhysicalDiskInfo, _T("N"), DCI_DT_STRING, DCIDESC_PHYSICALDISK_SERIALNUMBER },
302 { _T("PhysicalDisk.SmartAttr(*)"), H_PhysicalDiskInfo, _T("A"), DCI_DT_STRING, DCIDESC_PHYSICALDISK_SMARTATTR },
303 { _T("PhysicalDisk.SmartStatus(*)"), H_PhysicalDiskInfo, _T("S"), DCI_DT_INT, DCIDESC_PHYSICALDISK_SMARTSTATUS },
304 { _T("PhysicalDisk.Temperature(*)"), H_PhysicalDiskInfo, _T("T"), DCI_DT_INT, DCIDESC_PHYSICALDISK_TEMPERATURE },
305 { _T("System.CPU.Count"), H_CPUCount, NULL, DCI_DT_UINT, DCIDESC_SYSTEM_CPU_COUNT },
306 { _T("System.IsVirtual"), H_SystemIsVirtual, NULL, DCI_DT_INT, DCIDESC_SYSTEM_IS_VIRTUAL },
307 { _T("System.Memory.Physical.Available"), H_MemoryInfo, (TCHAR *)MEMINFO_PHYSICAL_FREE, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_PHYSICAL_AVAILABLE },
308 { _T("System.Memory.Physical.AvailablePerc"), H_MemoryInfo, (TCHAR *)MEMINFO_PHYSICAL_FREE_PCT, DCI_DT_FLOAT, DCIDESC_SYSTEM_MEMORY_PHYSICAL_AVAILABLE_PCT },
309 { _T("System.Memory.Physical.Free"), H_MemoryInfo, (TCHAR *)MEMINFO_PHYSICAL_FREE, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_PHYSICAL_FREE },
310 { _T("System.Memory.Physical.FreePerc"), H_MemoryInfo, (TCHAR *)MEMINFO_PHYSICAL_FREE_PCT, DCI_DT_FLOAT, DCIDESC_SYSTEM_MEMORY_PHYSICAL_FREE_PCT },
311 { _T("System.Memory.Physical.Total"), H_MemoryInfo, (TCHAR *)MEMINFO_PHYSICAL_TOTAL, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_PHYSICAL_TOTAL },
312 { _T("System.Memory.Physical.Used"), H_MemoryInfo, (TCHAR *)MEMINFO_PHYSICAL_USED, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_PHYSICAL_USED },
313 { _T("System.Memory.Physical.UsedPerc"), H_MemoryInfo, (TCHAR *)MEMINFO_PHYSICAL_USED_PCT, DCI_DT_FLOAT, DCIDESC_SYSTEM_MEMORY_PHYSICAL_USED_PCT },
314 { _T("System.Memory.Virtual.Free"), H_MemoryInfo, (TCHAR *)MEMINFO_VIRTUAL_FREE, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_VIRTUAL_FREE },
315 { _T("System.Memory.Virtual.FreePerc"), H_MemoryInfo, (TCHAR *)MEMINFO_VIRTUAL_FREE_PCT, DCI_DT_FLOAT, DCIDESC_SYSTEM_MEMORY_VIRTUAL_FREE_PCT },
316 { _T("System.Memory.Virtual.Total"), H_MemoryInfo, (TCHAR *)MEMINFO_VIRTUAL_TOTAL, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_VIRTUAL_TOTAL },
317 { _T("System.Memory.Virtual.Used"), H_MemoryInfo, (TCHAR *)MEMINFO_VIRTUAL_USED, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_VIRTUAL_USED },
318 { _T("System.Memory.Virtual.UsedPerc"), H_MemoryInfo, (TCHAR *)MEMINFO_VIRTUAL_USED_PCT, DCI_DT_FLOAT, DCIDESC_SYSTEM_MEMORY_VIRTUAL_USED_PCT },
319 { _T("System.Uname"), H_SystemUname, NULL, DCI_DT_STRING, DCIDESC_SYSTEM_UNAME },
320 #endif
321
322 #if HAVE_GET_CPUID
323 { _T("System.IsVirtual"), H_SystemIsVirtual, NULL, DCI_DT_INT, DCIDESC_SYSTEM_IS_VIRTUAL },
324 #endif
325
326 { _T("Agent.AcceptedConnections"), H_UIntPtr, (TCHAR *)&g_acceptedConnections, DCI_DT_UINT, DCIDESC_AGENT_ACCEPTEDCONNECTIONS },
327 { _T("Agent.AcceptErrors"), H_UIntPtr, (TCHAR *)&g_acceptErrors, DCI_DT_UINT, DCIDESC_AGENT_ACCEPTERRORS },
328 { _T("Agent.ActiveConnections"), H_ActiveConnections, NULL, DCI_DT_UINT, DCIDESC_AGENT_ACTIVECONNECTIONS },
329 { _T("Agent.AuthenticationFailures"), H_UIntPtr, (TCHAR *)&m_dwAuthenticationFailures, DCI_DT_UINT, DCIDESC_AGENT_AUTHENTICATIONFAILURES },
330 { _T("Agent.ConfigurationServer"), H_StringConstant, g_szConfigServer, DCI_DT_STRING, DCIDESC_AGENT_CONFIG_SERVER },
331 { _T("Agent.DataCollectorQueueSize"), H_DataCollectorQueueSize, NULL, DCI_DT_UINT, DCIDESC_AGENT_DATACOLLQUEUESIZE },
332 { _T("Agent.FailedRequests"), H_UIntPtr, (TCHAR *)&m_dwFailedRequests, DCI_DT_UINT, DCIDESC_AGENT_FAILEDREQUESTS },
333 { _T("Agent.GeneratedTraps"), H_AgentTraps, _T("G"), DCI_DT_UINT64, DCIDESC_AGENT_GENERATED_TRAPS },
334 { _T("Agent.IsSubagentLoaded(*)"), H_IsSubagentLoaded, NULL, DCI_DT_INT, DCIDESC_AGENT_IS_SUBAGENT_LOADED },
335 { _T("Agent.IsExternalSubagentConnected(*)"), H_IsExtSubagentConnected, NULL, DCI_DT_INT, DCIDESC_AGENT_IS_EXT_SUBAGENT_CONNECTED },
336 { _T("Agent.LastTrapTime"), H_AgentTraps, _T("T"), DCI_DT_UINT64, DCIDESC_AGENT_LAST_TRAP_TIME },
337 { _T("Agent.LocalDatabase.FailedQueries"), H_LocalDatabaseCounters, _T("F"), DCI_DT_UINT64, DCIDESC_AGENT_LOCALDB_FAILED_QUERIES },
338 { _T("Agent.LocalDatabase.LongRunningQueries"), H_LocalDatabaseCounters, _T("L"), DCI_DT_UINT64, DCIDESC_AGENT_LOCALDB_SLOW_QUERIES },
339 { _T("Agent.LocalDatabase.Status"), H_ComponentStatus, _T("D"), DCI_DT_UINT, DCIDESC_AGENT_LOCALDB_STATUS },
340 { _T("Agent.LocalDatabase.TotalQueries"), H_LocalDatabaseCounters, _T("T"), DCI_DT_UINT64, DCIDESC_AGENT_LOCALDB_TOTAL_QUERIES },
341 { _T("Agent.LogFile.Status"), H_ComponentStatus, _T("L"), DCI_DT_UINT, DCIDESC_AGENT_LOG_STATUS },
342 { _T("Agent.ProcessedRequests"), H_UIntPtr, (TCHAR *)&m_dwProcessedRequests, DCI_DT_UINT, DCIDESC_AGENT_PROCESSEDREQUESTS },
343 { _T("Agent.Proxy.ActiveSessions"), H_AgentProxyStats, _T("A"), DCI_DT_UINT, DCIDESC_AGENT_PROXY_ACTIVESESSIONS },
344 { _T("Agent.Proxy.ConnectionRequests"), H_AgentProxyStats, _T("C"), DCI_DT_UINT64, DCIDESC_AGENT_PROXY_CONNECTIONREQUESTS },
345 { _T("Agent.Proxy.IsEnabled"), H_FlagValue, CAST_TO_POINTER(AF_ENABLE_PROXY, TCHAR *), DCI_DT_UINT, DCIDESC_AGENT_PROXY_ISENABLED },
346 { _T("Agent.Registrar"), H_StringConstant, g_szRegistrar, DCI_DT_STRING, DCIDESC_AGENT_REGISTRAR },
347 { _T("Agent.RejectedConnections"), H_UIntPtr, (TCHAR *)&g_rejectedConnections, DCI_DT_UINT, DCIDESC_AGENT_REJECTEDCONNECTIONS },
348 { _T("Agent.SentTraps"), H_AgentTraps, _T("S"), DCI_DT_UINT64, DCIDESC_AGENT_SENT_TRAPS },
349 { _T("Agent.SNMP.IsProxyEnabled"), H_FlagValue, CAST_TO_POINTER(AF_ENABLE_SNMP_PROXY, TCHAR *), DCI_DT_UINT, DCIDESC_AGENT_SNMP_ISPROXYENABLED },
350 { _T("Agent.SNMP.IsTrapProxyEnabled"), H_FlagValue, CAST_TO_POINTER(AF_ENABLE_SNMP_TRAP_PROXY, TCHAR *), DCI_DT_UINT, DCIDESC_AGENT_SNMP_ISPROXYENABLED },
351 { _T("Agent.SNMP.Requests"), H_SNMPProxyStats, _T("R"), DCI_DT_UINT64, DCIDESC_AGENT_SNMP_REQUESTS },
352 { _T("Agent.SNMP.Responses"), H_SNMPProxyStats, _T("r"), DCI_DT_UINT64, DCIDESC_AGENT_SNMP_RESPONSES },
353 { _T("Agent.SNMP.ServerRequests"), H_SNMPProxyStats, _T("S"), DCI_DT_UINT64, DCIDESC_AGENT_SNMP_SERVERREQUESTS },
354 { _T("Agent.SourcePackageSupport"), H_StringConstant, _T("0"), DCI_DT_INT, DCIDESC_AGENT_SOURCEPACKAGESUPPORT },
355 { _T("Agent.SupportedCiphers"), H_SupportedCiphers, NULL, DCI_DT_STRING, DCIDESC_AGENT_SUPPORTEDCIPHERS },
356 { _T("Agent.SyslogProxy.IsEnabled"), H_FlagValue, CAST_TO_POINTER(AF_ENABLE_SYSLOG_PROXY, TCHAR *), DCI_DT_UINT, DCIDESC_AGENT_SYSLOGPROXY_ISENABLED },
357 { _T("Agent.SyslogProxy.ReceivedMessages"), H_SyslogStats, _T("R"), DCI_DT_UINT64, DCIDESC_AGENT_SYSLOGPROXY_RECEIVEDMSGS },
358 { _T("Agent.SyslogProxy.QueueSize"), H_SyslogStats, _T("Q"), DCI_DT_UINT, DCIDESC_AGENT_SYSLOGPROXY_QUEUESIZE },
359 { _T("Agent.ThreadPool.ActiveRequests(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_REQUESTS, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_ACTIVEREQUESTS },
360 { _T("Agent.ThreadPool.CurrSize(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_CURR_SIZE, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_CURRSIZE },
361 { _T("Agent.ThreadPool.Load(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_LOAD, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_LOAD },
362 { _T("Agent.ThreadPool.LoadAverage(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_LOADAVG_1, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_LOADAVG },
363 { _T("Agent.ThreadPool.LoadAverage5(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_LOADAVG_5, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_LOADAVG_5 },
364 { _T("Agent.ThreadPool.LoadAverage15(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_LOADAVG_15, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_LOADAVG_15 },
365 { _T("Agent.ThreadPool.MaxSize(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_MAX_SIZE, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_MAXSIZE },
366 { _T("Agent.ThreadPool.MinSize(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_MIN_SIZE, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_MINSIZE },
367 { _T("Agent.ThreadPool.Usage(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_USAGE, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_USAGE },
368 { _T("Agent.TimedOutRequests"), H_UIntPtr, (TCHAR *)&m_dwTimedOutRequests, DCI_DT_UINT, DCIDESC_AGENT_TIMEDOUTREQUESTS },
369 { _T("Agent.UnsupportedRequests"), H_UIntPtr, (TCHAR *)&m_dwUnsupportedRequests, DCI_DT_UINT, DCIDESC_AGENT_UNSUPPORTEDREQUESTS },
370 { _T("Agent.Uptime"), H_AgentUptime, NULL, DCI_DT_UINT, DCIDESC_AGENT_UPTIME },
371 { _T("Agent.Version"), H_StringConstant, NETXMS_BUILD_TAG, DCI_DT_STRING, DCIDESC_AGENT_VERSION },
372 { _T("File.Count(*)"), H_DirInfo, (TCHAR *)DIRINFO_FILE_COUNT, DCI_DT_UINT, DCIDESC_FILE_COUNT },
373 { _T("File.FolderCount(*)"), H_DirInfo, (TCHAR *)DIRINFO_FOLDER_COUNT, DCI_DT_UINT, DCIDESC_FILE_FOLDERCOUNT },
374 { _T("File.Hash.CRC32(*)"), H_CRC32, NULL, DCI_DT_UINT, DCIDESC_FILE_HASH_CRC32 },
375 { _T("File.Hash.MD5(*)"), H_MD5Hash, NULL, DCI_DT_STRING, DCIDESC_FILE_HASH_MD5 },
376 { _T("File.Hash.SHA1(*)"), H_SHA1Hash, NULL, DCI_DT_STRING, DCIDESC_FILE_HASH_SHA1 },
377 { _T("File.Size(*)"), H_DirInfo, (TCHAR *)DIRINFO_FILE_SIZE, DCI_DT_UINT64, DCIDESC_FILE_SIZE },
378 { _T("File.Time.Access(*)"), H_FileTime, (TCHAR *)FILETIME_ATIME, DCI_DT_UINT64, DCIDESC_FILE_TIME_ACCESS },
379 { _T("File.Time.Change(*)"), H_FileTime, (TCHAR *)FILETIME_CTIME, DCI_DT_UINT64, DCIDESC_FILE_TIME_CHANGE },
380 { _T("File.Time.Modify(*)"), H_FileTime, (TCHAR *)FILETIME_MTIME, DCI_DT_UINT64, DCIDESC_FILE_TIME_MODIFY },
381 { _T("Net.Resolver.AddressByName(*)"), H_ResolverAddrByName, NULL, DCI_DT_STRING, DCIDESC_NET_RESOLVER_ADDRBYNAME },
382 { _T("Net.Resolver.NameByAddress(*)"), H_ResolverNameByAddr, NULL, DCI_DT_STRING, DCIDESC_NET_RESOLVER_NAMEBYADDR },
383 { _T("System.CurrentTime"), H_SystemTime, NULL, DCI_DT_INT64, DCIDESC_SYSTEM_CURRENTTIME },
384 { _T("System.FQDN"), H_HostName, _T("FQDN"), DCI_DT_STRING, DCIDESC_SYSTEM_FQDN },
385 { _T("System.Hostname"), H_HostName, NULL, DCI_DT_STRING, DCIDESC_SYSTEM_HOSTNAME },
386 { _T("System.PlatformName"), H_PlatformName, NULL, DCI_DT_STRING, DCIDESC_SYSTEM_PLATFORMNAME }
387 };
388
389 /**
390 * Standard agent's lists
391 */
392 static NETXMS_SUBAGENT_LIST m_stdLists[] =
393 {
394 #ifdef _WIN32
395 { _T("FileSystem.MountPoints"), H_MountPoints, NULL },
396 #endif
397 { _T("Agent.ActionList"), H_ActionList, NULL },
398 { _T("Agent.SubAgentList"), H_SubAgentList, NULL },
399 { _T("Agent.SupportedLists"), H_EnumList, NULL },
400 { _T("Agent.SupportedParameters"), H_ParamList, NULL },
401 { _T("Agent.SupportedPushParameters"), H_PushParamList, NULL },
402 { _T("Agent.SupportedTables"), H_TableList, NULL },
403 { _T("Agent.ThreadPools"), H_ThreadPoolList, NULL }
404 };
405
406 /**
407 * Standard agent's tables
408 */
409 static NETXMS_SUBAGENT_TABLE m_stdTables[] =
410 {
411 { _T("Agent.SessionAgents"), H_SessionAgents, NULL, _T("SESSION_ID"), DCTDESC_AGENT_SUBAGENTS },
412 { _T("Agent.SubAgents"), H_SubAgentTable, NULL, _T("NAME"), DCTDESC_AGENT_SUBAGENTS },
413 #ifdef _WIN32
414 { _T("FileSystem.Volumes"), H_FileSystems, NULL, _T("VOLUME"), DCTDESC_FILESYSTEM_VOLUMES }
415 #endif
416 };
417
418 /**
419 * Initialize dynamic parameters list from default static list
420 */
421 BOOL InitParameterList()
422 {
423 if ((m_pParamList != NULL) || (m_pEnumList != NULL) || (m_pTableList != NULL))
424 return FALSE;
425
426 m_iNumParams = sizeof(m_stdParams) / sizeof(NETXMS_SUBAGENT_PARAM);
427 if (m_iNumParams > 0)
428 {
429 m_pParamList = (NETXMS_SUBAGENT_PARAM *)malloc(sizeof(NETXMS_SUBAGENT_PARAM) * m_iNumParams);
430 if (m_pParamList == NULL)
431 return FALSE;
432 memcpy(m_pParamList, m_stdParams, sizeof(NETXMS_SUBAGENT_PARAM) * m_iNumParams);
433 }
434
435 m_iNumEnums = sizeof(m_stdLists) / sizeof(NETXMS_SUBAGENT_LIST);
436 if (m_iNumEnums > 0)
437 {
438 m_pEnumList = (NETXMS_SUBAGENT_LIST *)malloc(sizeof(NETXMS_SUBAGENT_LIST) * m_iNumEnums);
439 if (m_pEnumList == NULL)
440 return FALSE;
441 memcpy(m_pEnumList, m_stdLists, sizeof(NETXMS_SUBAGENT_LIST) * m_iNumEnums);
442 }
443
444 m_iNumTables = sizeof(m_stdTables) / sizeof(NETXMS_SUBAGENT_TABLE);
445 if (m_iNumTables > 0)
446 {
447 m_pTableList = (NETXMS_SUBAGENT_TABLE *)malloc(sizeof(NETXMS_SUBAGENT_TABLE) * m_iNumTables);
448 if (m_pTableList == NULL)
449 return FALSE;
450 memcpy(m_pTableList, m_stdTables, sizeof(NETXMS_SUBAGENT_TABLE) * m_iNumTables);
451 }
452
453 return TRUE;
454 }
455
456 /**
457 * Add push parameter to list
458 * by LWX
459 */
460 void AddPushParameter(const TCHAR *name, int dataType, const TCHAR *description)
461 {
462 int i;
463
464 // Search for existing parameter
465 for(i = 0; i < m_iNumPushParams; i++)
466 if (!_tcsicmp(m_pPushParamList[i].name, name))
467 break;
468 if (i < m_iNumPushParams)
469 {
470 // Replace existing attributes
471 m_pPushParamList[i].dataType = dataType;
472 nx_strncpy(m_pPushParamList[i].description, description, MAX_DB_STRING);
473 }
474 else
475 {
476 // Add new parameter
477 m_pPushParamList = (NETXMS_SUBAGENT_PUSHPARAM *)realloc(m_pPushParamList, sizeof(NETXMS_SUBAGENT_PUSHPARAM) * (m_iNumPushParams + 1));
478 nx_strncpy(m_pPushParamList[m_iNumPushParams].name, name, MAX_PARAM_NAME - 1);
479 m_pPushParamList[m_iNumPushParams].dataType = dataType;
480 nx_strncpy(m_pPushParamList[m_iNumPushParams].description, description, MAX_DB_STRING);
481 m_iNumPushParams++;
482 }
483 }
484
485 /**
486 * Add parameter to list
487 */
488 void AddParameter(const TCHAR *pszName, LONG (* fpHandler)(const TCHAR *, const TCHAR *, TCHAR *, AbstractCommSession *), const TCHAR *pArg,
489 int iDataType, const TCHAR *pszDescription)
490 {
491 int i;
492
493 // Search for existing parameter
494 for(i = 0; i < m_iNumParams; i++)
495 if (!_tcsicmp(m_pParamList[i].name, pszName))
496 break;
497 if (i < m_iNumParams)
498 {
499 // Replace existing handler and attributes
500 m_pParamList[i].handler = fpHandler;
501 m_pParamList[i].dataType = iDataType;
502 nx_strncpy(m_pParamList[i].description, pszDescription, MAX_DB_STRING);
503
504 // If we are replacing System.PlatformName, add pointer to
505 // platform suffix as argument, otherwise, use supplied pArg
506 if (!_tcscmp(pszName, _T("System.PlatformName")))
507 {
508 m_pParamList[i].arg = g_szPlatformSuffix; // to be TCHAR
509 }
510 else
511 {
512 m_pParamList[i].arg = pArg;
513 }
514 }
515 else
516 {
517 // Add new parameter
518 m_pParamList = (NETXMS_SUBAGENT_PARAM *)realloc(m_pParamList, sizeof(NETXMS_SUBAGENT_PARAM) * (m_iNumParams + 1));
519 nx_strncpy(m_pParamList[m_iNumParams].name, pszName, MAX_PARAM_NAME - 1);
520 m_pParamList[m_iNumParams].handler = fpHandler;
521 m_pParamList[m_iNumParams].arg = pArg;
522 m_pParamList[m_iNumParams].dataType = iDataType;
523 nx_strncpy(m_pParamList[m_iNumParams].description, pszDescription, MAX_DB_STRING);
524 m_iNumParams++;
525 }
526 }
527
528 /**
529 * Add list
530 */
531 void AddList(const TCHAR *name, LONG (* handler)(const TCHAR *, const TCHAR *, StringList *, AbstractCommSession *), const TCHAR *arg)
532 {
533 int i;
534
535 // Search for existing enum
536 for(i = 0; i < m_iNumEnums; i++)
537 if (!_tcsicmp(m_pEnumList[i].name, name))
538 break;
539 if (i < m_iNumEnums)
540 {
541 // Replace existing handler and arg
542 m_pEnumList[i].handler = handler;
543 m_pEnumList[i].arg = arg;
544 }
545 else
546 {
547 // Add new enum
548 m_pEnumList = (NETXMS_SUBAGENT_LIST *)realloc(m_pEnumList, sizeof(NETXMS_SUBAGENT_LIST) * (m_iNumEnums + 1));
549 nx_strncpy(m_pEnumList[m_iNumEnums].name, name, MAX_PARAM_NAME - 1);
550 m_pEnumList[m_iNumEnums].handler = handler;
551 m_pEnumList[m_iNumEnums].arg = arg;
552 m_iNumEnums++;
553 }
554 }
555
556 /**
557 * Add table
558 */
559 void AddTable(const TCHAR *name, LONG (* handler)(const TCHAR *, const TCHAR *, Table *, AbstractCommSession *), const TCHAR *arg,
560 const TCHAR *instanceColumns, const TCHAR *description, int numColumns, NETXMS_SUBAGENT_TABLE_COLUMN *columns)
561 {
562 int i;
563
564 // Search for existing table
565 for(i = 0; i < m_iNumTables; i++)
566 if (!_tcsicmp(m_pTableList[i].name, name))
567 break;
568 if (i < m_iNumTables)
569 {
570 // Replace existing handler and arg
571 m_pTableList[i].handler = handler;
572 m_pTableList[i].arg = arg;
573 nx_strncpy(m_pTableList[m_iNumTables].instanceColumns, instanceColumns, MAX_COLUMN_NAME * MAX_INSTANCE_COLUMNS);
574 nx_strncpy(m_pTableList[m_iNumTables].description, description, MAX_DB_STRING);
575 m_pTableList[i].numColumns = numColumns;
576 m_pTableList[i].columns = columns;
577 }
578 else
579 {
580 // Add new table
581 m_pTableList = (NETXMS_SUBAGENT_TABLE *)realloc(m_pTableList, sizeof(NETXMS_SUBAGENT_TABLE) * (m_iNumTables + 1));
582 nx_strncpy(m_pTableList[m_iNumTables].name, name, MAX_PARAM_NAME);
583 m_pTableList[m_iNumTables].handler = handler;
584 m_pTableList[m_iNumTables].arg = arg;
585 nx_strncpy(m_pTableList[m_iNumTables].instanceColumns, instanceColumns, MAX_COLUMN_NAME * MAX_INSTANCE_COLUMNS);
586 nx_strncpy(m_pTableList[m_iNumTables].description, description, MAX_DB_STRING);
587 m_pTableList[m_iNumTables].numColumns = numColumns;
588 m_pTableList[m_iNumTables].columns = columns;
589 m_iNumTables++;
590 }
591 }
592
593 /**
594 * Add external parameter or list
595 */
596 bool AddExternalParameter(TCHAR *config, bool shellExec, bool isList)
597 {
598 TCHAR *cmdLine = _tcschr(config, _T(':'));
599 if (cmdLine == NULL)
600 return false;
601
602 *cmdLine = 0;
603 cmdLine++;
604 Trim(config);
605 Trim(cmdLine);
606 if ((*config == 0) || (*cmdLine == 0))
607 return false;
608
609 TCHAR *arg = (TCHAR *)malloc((_tcslen(cmdLine) + 2) * sizeof(TCHAR));
610 arg[0] = shellExec ? _T('S') : _T('E');
611 _tcscpy(&arg[1], cmdLine);
612 if (isList)
613 {
614 AddList(config, H_ExternalList, arg);
615 }
616 else
617 {
618 AddParameter(config, H_ExternalParameter, arg, DCI_DT_STRING, _T(""));
619 }
620 return true;
621 }
622
623 /**
624 * Add external table
625 */
626 bool AddExternalTable(TCHAR *config, bool shellExec)
627 {
628 TCHAR *options = _tcschr(config, _T(':'));
629 if (options == NULL)
630 return false;
631 *options = 0;
632 options++;
633
634 TCHAR *cmdLine = _tcschr(options, _T(':'));
635 if (cmdLine == NULL)
636 return false;
637 *cmdLine = 0;
638 cmdLine++;
639
640 Trim(config);
641 Trim(options);
642 Trim(cmdLine);
643 if ((*config == 0) || (*options == 0) || (*cmdLine == 0))
644 return false;
645
646 TCHAR instanceColumns[256] = _T("");
647 ExtractNamedOptionValue(options, _T("instanceColumns"), instanceColumns, 256);
648
649 TCHAR description[256] = _T("");
650 ExtractNamedOptionValue(options, _T("description"), description, 256);
651
652 TCHAR separator[16] = _T(",");
653 ExtractNamedOptionValue(options, _T("separator"), separator, 16);
654 if (separator[0] == _T('\\'))
655 {
656 switch(separator[1])
657 {
658 case 'n':
659 separator[0] = _T('\n');
660 break;
661 case 'r':
662 separator[0] = _T('\r');
663 break;
664 case 's':
665 separator[0] = _T(' ');
666 break;
667 case 't':
668 separator[0] = _T('\t');
669 break;
670 case 'u':
671 separator[0] = (TCHAR)_tcstoul(&separator[2], NULL, 10);
672 break;
673 }
674 }
675
676 TCHAR *arg = (TCHAR *)malloc((_tcslen(cmdLine) + 3) * sizeof(TCHAR));
677 arg[0] = separator[0];
678 arg[1] = shellExec ? _T('S') : _T('E');
679 _tcscpy(&arg[2], cmdLine);
680 AddTable(config, H_ExternalTable, arg, instanceColumns, description, 0, NULL);
681 return true;
682 }
683
684 /**
685 * Get parameter's value
686 */
687 UINT32 GetParameterValue(const TCHAR *param, TCHAR *value, AbstractCommSession *session)
688 {
689 int i, rc;
690 UINT32 dwErrorCode;
691
692 session->debugPrintf(5, _T("Requesting parameter \"%s\""), param);
693 for(i = 0; i < m_iNumParams; i++)
694 {
695 if (MatchString(m_pParamList[i].name, param, FALSE))
696 {
697 rc = m_pParamList[i].handler(param, m_pParamList[i].arg, value, session);
698 switch(rc)
699 {
700 case SYSINFO_RC_SUCCESS:
701 dwErrorCode = ERR_SUCCESS;
702 m_dwProcessedRequests++;
703 break;
704 case SYSINFO_RC_ERROR:
705 dwErrorCode = ERR_INTERNAL_ERROR;
706 m_dwFailedRequests++;
707 break;
708 case SYSINFO_RC_NO_SUCH_INSTANCE:
709 dwErrorCode = ERR_NO_SUCH_INSTANCE;
710 m_dwFailedRequests++;
711 break;
712 case SYSINFO_RC_UNSUPPORTED:
713 dwErrorCode = ERR_UNKNOWN_PARAMETER;
714 m_dwUnsupportedRequests++;
715 break;
716 default:
717 nxlog_write(MSG_UNEXPECTED_IRC, EVENTLOG_ERROR_TYPE, "ds", rc, param);
718 dwErrorCode = ERR_INTERNAL_ERROR;
719 m_dwFailedRequests++;
720 break;
721 }
722 break;
723 }
724 }
725
726 if (i == m_iNumParams)
727 {
728 rc = GetParameterValueFromExtProvider(param, value);
729 if (rc == SYSINFO_RC_SUCCESS)
730 {
731 dwErrorCode = ERR_SUCCESS;
732 m_dwProcessedRequests++;
733 }
734 else
735 {
736 dwErrorCode = ERR_UNKNOWN_PARAMETER;
737 }
738 }
739
740 if ((dwErrorCode == ERR_UNKNOWN_PARAMETER) && (i == m_iNumParams))
741 {
742 dwErrorCode = GetParameterValueFromAppAgent(param, value);
743 if (dwErrorCode == ERR_SUCCESS)
744 {
745 m_dwProcessedRequests++;
746 }
747 else if (dwErrorCode != ERR_UNKNOWN_PARAMETER)
748 {
749 m_dwFailedRequests++;
750 }
751 }
752
753 if ((dwErrorCode == ERR_UNKNOWN_PARAMETER) && (i == m_iNumParams))
754 {
755 dwErrorCode = GetParameterValueFromExtSubagent(param, value);
756 if (dwErrorCode == ERR_SUCCESS)
757 {
758 m_dwProcessedRequests++;
759 }
760 else if (dwErrorCode == ERR_UNKNOWN_PARAMETER)
761 {
762 m_dwUnsupportedRequests++;
763 }
764 else
765 {
766 m_dwFailedRequests++;
767 }
768 }
769
770 session->debugPrintf(7, _T("GetParameterValue(): result is %d (%s)"), (int)dwErrorCode,
771 dwErrorCode == ERR_SUCCESS ? _T("SUCCESS") : (dwErrorCode == ERR_UNKNOWN_PARAMETER ? _T("UNKNOWN_PARAMETER") : _T("INTERNAL_ERROR")));
772 return dwErrorCode;
773 }
774
775 /**
776 * Get list's value
777 */
778 UINT32 GetListValue(const TCHAR *param, StringList *value, AbstractCommSession *session)
779 {
780 int i, rc;
781 UINT32 dwErrorCode;
782
783 session->debugPrintf(5, _T("Requesting list \"%s\""), param);
784 for(i = 0; i < m_iNumEnums; i++)
785 {
786 if (MatchString(m_pEnumList[i].name, param, FALSE))
787 {
788 rc = m_pEnumList[i].handler(param, m_pEnumList[i].arg, value, session);
789 switch(rc)
790 {
791 case SYSINFO_RC_SUCCESS:
792 dwErrorCode = ERR_SUCCESS;
793 m_dwProcessedRequests++;
794 break;
795 case SYSINFO_RC_ERROR:
796 dwErrorCode = ERR_INTERNAL_ERROR;
797 m_dwFailedRequests++;
798 break;
799 case SYSINFO_RC_NO_SUCH_INSTANCE:
800 dwErrorCode = ERR_NO_SUCH_INSTANCE;
801 m_dwFailedRequests++;
802 break;
803 case SYSINFO_RC_UNSUPPORTED:
804 dwErrorCode = ERR_UNKNOWN_PARAMETER;
805 m_dwUnsupportedRequests++;
806 break;
807 default:
808 nxlog_write(MSG_UNEXPECTED_IRC, EVENTLOG_ERROR_TYPE, "ds", rc, param);
809 dwErrorCode = ERR_INTERNAL_ERROR;
810 m_dwFailedRequests++;
811 break;
812 }
813 break;
814 }
815 }
816
817 if (i == m_iNumEnums)
818 {
819 dwErrorCode = GetListValueFromExtSubagent(param, value);
820 if (dwErrorCode == ERR_SUCCESS)
821 {
822 m_dwProcessedRequests++;
823 }
824 else if (dwErrorCode == ERR_UNKNOWN_PARAMETER)
825 {
826 m_dwUnsupportedRequests++;
827 }
828 else
829 {
830 m_dwFailedRequests++;
831 }
832 }
833
834 session->debugPrintf(7, _T("GetListValue(): result is %d (%s)"), (int)dwErrorCode,
835 dwErrorCode == ERR_SUCCESS ? _T("SUCCESS") : (dwErrorCode == ERR_UNKNOWN_PARAMETER ? _T("UNKNOWN_PARAMETER") : _T("INTERNAL_ERROR")));
836 return dwErrorCode;
837 }
838
839 /**
840 * Get table's value
841 */
842 UINT32 GetTableValue(const TCHAR *param, Table *value, AbstractCommSession *session)
843 {
844 int i, rc;
845 UINT32 dwErrorCode;
846
847 session->debugPrintf(5, _T("Requesting table \"%s\""), param);
848 for(i = 0; i < m_iNumTables; i++)
849 {
850 if (MatchString(m_pTableList[i].name, param, FALSE))
851 {
852 // pre-fill table columns if specified in table definition
853 if (m_pTableList[i].numColumns > 0)
854 {
855 for(int c = 0; c < m_pTableList[i].numColumns; c++)
856 {
857 NETXMS_SUBAGENT_TABLE_COLUMN *col = &m_pTableList[i].columns[c];
858 value->addColumn(col->name, col->dataType, col->displayName, col->isInstance);
859 }
860 }
861
862 rc = m_pTableList[i].handler(param, m_pTableList[i].arg, value, session);
863 switch(rc)
864 {
865 case SYSINFO_RC_SUCCESS:
866 dwErrorCode = ERR_SUCCESS;
867 m_dwProcessedRequests++;
868 break;
869 case SYSINFO_RC_ERROR:
870 dwErrorCode = ERR_INTERNAL_ERROR;
871 m_dwFailedRequests++;
872 break;
873 case SYSINFO_RC_NO_SUCH_INSTANCE:
874 dwErrorCode = ERR_NO_SUCH_INSTANCE;
875 m_dwFailedRequests++;
876 break;
877 case SYSINFO_RC_UNSUPPORTED:
878 dwErrorCode = ERR_UNKNOWN_PARAMETER;
879 m_dwUnsupportedRequests++;
880 break;
881 default:
882 nxlog_write(MSG_UNEXPECTED_IRC, EVENTLOG_ERROR_TYPE, "ds", rc, param);
883 dwErrorCode = ERR_INTERNAL_ERROR;
884 m_dwFailedRequests++;
885 break;
886 }
887 break;
888 }
889 }
890
891 if (i == m_iNumTables)
892 {
893 dwErrorCode = GetTableValueFromExtSubagent(param, value);
894 if (dwErrorCode == ERR_SUCCESS)
895 {
896 m_dwProcessedRequests++;
897 }
898 else if (dwErrorCode == ERR_UNKNOWN_PARAMETER)
899 {
900 m_dwUnsupportedRequests++;
901 }
902 else
903 {
904 m_dwFailedRequests++;
905 }
906 }
907
908 session->debugPrintf(7, _T("GetTableValue(): result is %d (%s)"), (int)dwErrorCode,
909 dwErrorCode == ERR_SUCCESS ? _T("SUCCESS") : (dwErrorCode == ERR_UNKNOWN_PARAMETER ? _T("UNKNOWN_PARAMETER") : _T("INTERNAL_ERROR")));
910 return dwErrorCode;
911 }
912
913 /**
914 * Put complete list of supported parameters into NXCP message
915 */
916 void GetParameterList(NXCPMessage *pMsg)
917 {
918 int i;
919 UINT32 dwId, count;
920
921 // Parameters
922 for(i = 0, count = 0, dwId = VID_PARAM_LIST_BASE; i < m_iNumParams; i++)
923 {
924 if (m_pParamList[i].dataType != DCI_DT_DEPRECATED)
925 {
926 pMsg->setField(dwId++, m_pParamList[i].name);
927 pMsg->setField(dwId++, m_pParamList[i].description);
928 pMsg->setField(dwId++, (WORD)m_pParamList[i].dataType);
929 count++;
930 }
931 }
932 ListParametersFromExtProviders(pMsg, &dwId, &count);
933 ListParametersFromExtSubagents(pMsg, &dwId, &count);
934 pMsg->setField(VID_NUM_PARAMETERS, count);
935
936 // Push parameters
937 pMsg->setField(VID_NUM_PUSH_PARAMETERS, (UINT32)m_iNumPushParams);
938 for(i = 0, dwId = VID_PUSHPARAM_LIST_BASE; i < m_iNumPushParams; i++)
939 {
940 pMsg->setField(dwId++, m_pPushParamList[i].name);
941 pMsg->setField(dwId++, m_pPushParamList[i].description);
942 pMsg->setField(dwId++, (WORD)m_pPushParamList[i].dataType);
943 }
944
945 // Lists
946 pMsg->setField(VID_NUM_ENUMS, (UINT32)m_iNumEnums);
947 for(i = 0, dwId = VID_ENUM_LIST_BASE; i < m_iNumEnums; i++)
948 {
949 pMsg->setField(dwId++, m_pEnumList[i].name);
950 }
951 ListListsFromExtSubagents(pMsg, &dwId, &count);
952
953 // Tables
954 pMsg->setField(VID_NUM_TABLES, (UINT32)m_iNumTables);
955 for(i = 0, dwId = VID_TABLE_LIST_BASE; i < m_iNumTables; i++)
956 {
957 pMsg->setField(dwId++, m_pTableList[i].name);
958 pMsg->setField(dwId++, m_pTableList[i].instanceColumns);
959 pMsg->setField(dwId++, m_pTableList[i].description);
960 }
961 ListTablesFromExtSubagents(pMsg, &dwId, &count);
962 }
963
964 /**
965 * Put list of supported tables into NXCP message
966 */
967 void GetTableList(NXCPMessage *pMsg)
968 {
969 int i;
970 UINT32 dwId, count;
971
972 pMsg->setField(VID_NUM_TABLES, (UINT32)m_iNumTables);
973 for(i = 0, dwId = VID_TABLE_LIST_BASE; i < m_iNumTables; i++)
974 {
975 pMsg->setField(dwId++, m_pTableList[i].name);
976 pMsg->setField(dwId++, m_pTableList[i].instanceColumns);
977 pMsg->setField(dwId++, m_pTableList[i].description);
978 }
979 ListTablesFromExtSubagents(pMsg, &dwId, &count);
980 }
981
982 /**
983 * Put list of supported lists (enums) into NXCP message
984 */
985 void GetEnumList(NXCPMessage *pMsg)
986 {
987 int i;
988 UINT32 dwId, count;
989
990 pMsg->setField(VID_NUM_ENUMS, (UINT32)m_iNumEnums);
991 for(i = 0, dwId = VID_ENUM_LIST_BASE; i < m_iNumEnums; i++)
992 {
993 pMsg->setField(dwId++, m_pEnumList[i].name);
994 }
995 ListListsFromExtSubagents(pMsg, &dwId, &count);
996 }