implemented agent parameter Agent.IsExternalSubagentConnected
[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_IsExtSubagentConnected(const TCHAR *pszCmd, const TCHAR *pArg, TCHAR *pValue, AbstractCommSession *session);
47 LONG H_IsSubagentLoaded(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
48 LONG H_MD5Hash(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
49 LONG H_PlatformName(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
50 LONG H_ResolverAddrByName(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
51 LONG H_ResolverNameByAddr(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
52 LONG H_SessionAgents(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractCommSession *session);
53 LONG H_SHA1Hash(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
54 LONG H_SNMPProxyStats(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
55 LONG H_SubAgentList(const TCHAR *cmd, const TCHAR *arg, StringList *value, AbstractCommSession *session);
56 LONG H_SubAgentTable(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractCommSession *session);
57 LONG H_SyslogStats(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
58 LONG H_SystemTime(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
59 LONG H_ThreadPoolInfo(const TCHAR *param, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
60 LONG H_ThreadPoolList(const TCHAR *param, const TCHAR *arg, StringList *value, AbstractCommSession *session);
61
62 #ifdef _WIN32
63 LONG H_CPUCount(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
64 LONG H_DiskInfo(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
65 LONG H_FileSystems(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractCommSession *session);
66 LONG H_FileSystemType(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
67 LONG H_HostName(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.Hostname"), H_HostName, NULL, DCI_DT_STRING, DCIDESC_SYSTEM_HOSTNAME },
307 { _T("System.IsVirtual"), H_SystemIsVirtual, NULL, DCI_DT_INT, DCIDESC_SYSTEM_IS_VIRTUAL },
308 { _T("System.Memory.Physical.Available"), H_MemoryInfo, (TCHAR *)MEMINFO_PHYSICAL_FREE, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_PHYSICAL_AVAILABLE },
309 { _T("System.Memory.Physical.AvailablePerc"), H_MemoryInfo, (TCHAR *)MEMINFO_PHYSICAL_FREE_PCT, DCI_DT_FLOAT, DCIDESC_SYSTEM_MEMORY_PHYSICAL_AVAILABLE_PCT },
310 { _T("System.Memory.Physical.Free"), H_MemoryInfo, (TCHAR *)MEMINFO_PHYSICAL_FREE, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_PHYSICAL_FREE },
311 { _T("System.Memory.Physical.FreePerc"), H_MemoryInfo, (TCHAR *)MEMINFO_PHYSICAL_FREE_PCT, DCI_DT_FLOAT, DCIDESC_SYSTEM_MEMORY_PHYSICAL_FREE_PCT },
312 { _T("System.Memory.Physical.Total"), H_MemoryInfo, (TCHAR *)MEMINFO_PHYSICAL_TOTAL, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_PHYSICAL_TOTAL },
313 { _T("System.Memory.Physical.Used"), H_MemoryInfo, (TCHAR *)MEMINFO_PHYSICAL_USED, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_PHYSICAL_USED },
314 { _T("System.Memory.Physical.UsedPerc"), H_MemoryInfo, (TCHAR *)MEMINFO_PHYSICAL_USED_PCT, DCI_DT_FLOAT, DCIDESC_SYSTEM_MEMORY_PHYSICAL_USED_PCT },
315 { _T("System.Memory.Virtual.Free"), H_MemoryInfo, (TCHAR *)MEMINFO_VIRTUAL_FREE, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_VIRTUAL_FREE },
316 { _T("System.Memory.Virtual.FreePerc"), H_MemoryInfo, (TCHAR *)MEMINFO_VIRTUAL_FREE_PCT, DCI_DT_FLOAT, DCIDESC_SYSTEM_MEMORY_VIRTUAL_FREE_PCT },
317 { _T("System.Memory.Virtual.Total"), H_MemoryInfo, (TCHAR *)MEMINFO_VIRTUAL_TOTAL, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_VIRTUAL_TOTAL },
318 { _T("System.Memory.Virtual.Used"), H_MemoryInfo, (TCHAR *)MEMINFO_VIRTUAL_USED, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_VIRTUAL_USED },
319 { _T("System.Memory.Virtual.UsedPerc"), H_MemoryInfo, (TCHAR *)MEMINFO_VIRTUAL_USED_PCT, DCI_DT_FLOAT, DCIDESC_SYSTEM_MEMORY_VIRTUAL_USED_PCT },
320 { _T("System.Uname"), H_SystemUname, NULL, DCI_DT_STRING, DCIDESC_SYSTEM_UNAME },
321 #endif
322
323 #if HAVE_GET_CPUID
324 { _T("System.IsVirtual"), H_SystemIsVirtual, NULL, DCI_DT_INT, DCIDESC_SYSTEM_IS_VIRTUAL },
325 #endif
326
327 { _T("Agent.AcceptedConnections"), H_UIntPtr, (TCHAR *)&g_acceptedConnections, DCI_DT_UINT, DCIDESC_AGENT_ACCEPTEDCONNECTIONS },
328 { _T("Agent.AcceptErrors"), H_UIntPtr, (TCHAR *)&g_acceptErrors, DCI_DT_UINT, DCIDESC_AGENT_ACCEPTERRORS },
329 { _T("Agent.ActiveConnections"), H_ActiveConnections, NULL, DCI_DT_UINT, DCIDESC_AGENT_ACTIVECONNECTIONS },
330 { _T("Agent.AuthenticationFailures"), H_UIntPtr, (TCHAR *)&m_dwAuthenticationFailures, DCI_DT_UINT, DCIDESC_AGENT_AUTHENTICATIONFAILURES },
331 { _T("Agent.ConfigurationServer"), H_StringConstant, g_szConfigServer, DCI_DT_STRING, DCIDESC_AGENT_CONFIG_SERVER },
332 { _T("Agent.DataCollectorQueueSize"), H_DataCollectorQueueSize, NULL, DCI_DT_UINT, DCIDESC_AGENT_DATACOLLQUEUESIZE },
333 { _T("Agent.FailedRequests"), H_UIntPtr, (TCHAR *)&m_dwFailedRequests, DCI_DT_UINT, DCIDESC_AGENT_FAILEDREQUESTS },
334 { _T("Agent.GeneratedTraps"), H_AgentTraps, _T("G"), DCI_DT_UINT64, DCIDESC_AGENT_GENERATED_TRAPS },
335 { _T("Agent.IsSubagentLoaded(*)"), H_IsSubagentLoaded, NULL, DCI_DT_INT, DCIDESC_AGENT_IS_SUBAGENT_LOADED },
336 { _T("Agent.IsExternalSubagentConnected(*)"), H_IsExtSubagentConnected, NULL, DCI_DT_INT, DCIDESC_AGENT_IS_EXT_SUBAGENT_CONNECTED },
337 { _T("Agent.LastTrapTime"), H_AgentTraps, _T("T"), DCI_DT_UINT64, DCIDESC_AGENT_LAST_TRAP_TIME },
338 { _T("Agent.LocalDatabase.FailedQueries"), H_LocalDatabaseCounters, _T("F"), DCI_DT_UINT64, DCIDESC_AGENT_LOCALDB_FAILED_QUERIES },
339 { _T("Agent.LocalDatabase.LongRunningQueries"), H_LocalDatabaseCounters, _T("L"), DCI_DT_UINT64, DCIDESC_AGENT_LOCALDB_SLOW_QUERIES },
340 { _T("Agent.LocalDatabase.Status"), H_ComponentStatus, _T("D"), DCI_DT_UINT, DCIDESC_AGENT_LOCALDB_STATUS },
341 { _T("Agent.LocalDatabase.TotalQueries"), H_LocalDatabaseCounters, _T("T"), DCI_DT_UINT64, DCIDESC_AGENT_LOCALDB_TOTAL_QUERIES },
342 { _T("Agent.LogFile.Status"), H_ComponentStatus, _T("L"), DCI_DT_UINT, DCIDESC_AGENT_LOG_STATUS },
343 { _T("Agent.ProcessedRequests"), H_UIntPtr, (TCHAR *)&m_dwProcessedRequests, DCI_DT_UINT, DCIDESC_AGENT_PROCESSEDREQUESTS },
344 { _T("Agent.Proxy.ActiveSessions"), H_AgentProxyStats, _T("A"), DCI_DT_UINT, DCIDESC_AGENT_PROXY_ACTIVESESSIONS },
345 { _T("Agent.Proxy.ConnectionRequests"), H_AgentProxyStats, _T("C"), DCI_DT_UINT64, DCIDESC_AGENT_PROXY_CONNECTIONREQUESTS },
346 { _T("Agent.Proxy.IsEnabled"), H_FlagValue, CAST_TO_POINTER(AF_ENABLE_PROXY, TCHAR *), DCI_DT_UINT, DCIDESC_AGENT_PROXY_ISENABLED },
347 { _T("Agent.Registrar"), H_StringConstant, g_szRegistrar, DCI_DT_STRING, DCIDESC_AGENT_REGISTRAR },
348 { _T("Agent.RejectedConnections"), H_UIntPtr, (TCHAR *)&g_rejectedConnections, DCI_DT_UINT, DCIDESC_AGENT_REJECTEDCONNECTIONS },
349 { _T("Agent.SentTraps"), H_AgentTraps, _T("S"), DCI_DT_UINT64, DCIDESC_AGENT_SENT_TRAPS },
350 { _T("Agent.SNMP.IsProxyEnabled"), H_FlagValue, CAST_TO_POINTER(AF_ENABLE_SNMP_PROXY, TCHAR *), DCI_DT_UINT, DCIDESC_AGENT_SNMP_ISPROXYENABLED },
351 { _T("Agent.SNMP.IsTrapProxyEnabled"), H_FlagValue, CAST_TO_POINTER(AF_ENABLE_SNMP_TRAP_PROXY, TCHAR *), DCI_DT_UINT, DCIDESC_AGENT_SNMP_ISPROXYENABLED },
352 { _T("Agent.SNMP.Requests"), H_SNMPProxyStats, _T("R"), DCI_DT_UINT64, DCIDESC_AGENT_SNMP_REQUESTS },
353 { _T("Agent.SNMP.Responses"), H_SNMPProxyStats, _T("r"), DCI_DT_UINT64, DCIDESC_AGENT_SNMP_RESPONSES },
354 { _T("Agent.SNMP.ServerRequests"), H_SNMPProxyStats, _T("S"), DCI_DT_UINT64, DCIDESC_AGENT_SNMP_SERVERREQUESTS },
355 { _T("Agent.SourcePackageSupport"), H_StringConstant, _T("0"), DCI_DT_INT, DCIDESC_AGENT_SOURCEPACKAGESUPPORT },
356 { _T("Agent.SupportedCiphers"), H_SupportedCiphers, NULL, DCI_DT_STRING, DCIDESC_AGENT_SUPPORTEDCIPHERS },
357 { _T("Agent.SyslogProxy.IsEnabled"), H_FlagValue, CAST_TO_POINTER(AF_ENABLE_SYSLOG_PROXY, TCHAR *), DCI_DT_UINT, DCIDESC_AGENT_SYSLOGPROXY_ISENABLED },
358 { _T("Agent.SyslogProxy.ReceivedMessages"), H_SyslogStats, _T("R"), DCI_DT_UINT64, DCIDESC_AGENT_SYSLOGPROXY_RECEIVEDMSGS },
359 { _T("Agent.SyslogProxy.QueueSize"), H_SyslogStats, _T("Q"), DCI_DT_UINT, DCIDESC_AGENT_SYSLOGPROXY_QUEUESIZE },
360 { _T("Agent.ThreadPool.ActiveRequests(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_REQUESTS, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_ACTIVEREQUESTS },
361 { _T("Agent.ThreadPool.CurrSize(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_CURR_SIZE, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_CURRSIZE },
362 { _T("Agent.ThreadPool.Load(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_LOAD, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_LOAD },
363 { _T("Agent.ThreadPool.LoadAverage(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_LOADAVG_1, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_LOADAVG },
364 { _T("Agent.ThreadPool.LoadAverage5(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_LOADAVG_5, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_LOADAVG_5 },
365 { _T("Agent.ThreadPool.LoadAverage15(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_LOADAVG_15, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_LOADAVG_15 },
366 { _T("Agent.ThreadPool.MaxSize(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_MAX_SIZE, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_MAXSIZE },
367 { _T("Agent.ThreadPool.MinSize(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_MIN_SIZE, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_MINSIZE },
368 { _T("Agent.ThreadPool.Usage(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_USAGE, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_USAGE },
369 { _T("Agent.TimedOutRequests"), H_UIntPtr, (TCHAR *)&m_dwTimedOutRequests, DCI_DT_UINT, DCIDESC_AGENT_TIMEDOUTREQUESTS },
370 { _T("Agent.UnsupportedRequests"), H_UIntPtr, (TCHAR *)&m_dwUnsupportedRequests, DCI_DT_UINT, DCIDESC_AGENT_UNSUPPORTEDREQUESTS },
371 { _T("Agent.Uptime"), H_AgentUptime, NULL, DCI_DT_UINT, DCIDESC_AGENT_UPTIME },
372 { _T("Agent.Version"), H_StringConstant, NETXMS_BUILD_TAG, DCI_DT_STRING, DCIDESC_AGENT_VERSION },
373 { _T("File.Count(*)"), H_DirInfo, (TCHAR *)DIRINFO_FILE_COUNT, DCI_DT_UINT, DCIDESC_FILE_COUNT },
374 { _T("File.FolderCount(*)"), H_DirInfo, (TCHAR *)DIRINFO_FOLDER_COUNT, DCI_DT_UINT, DCIDESC_FILE_FOLDERCOUNT },
375 { _T("File.Hash.CRC32(*)"), H_CRC32, NULL, DCI_DT_UINT, DCIDESC_FILE_HASH_CRC32 },
376 { _T("File.Hash.MD5(*)"), H_MD5Hash, NULL, DCI_DT_STRING, DCIDESC_FILE_HASH_MD5 },
377 { _T("File.Hash.SHA1(*)"), H_SHA1Hash, NULL, DCI_DT_STRING, DCIDESC_FILE_HASH_SHA1 },
378 { _T("File.Size(*)"), H_DirInfo, (TCHAR *)DIRINFO_FILE_SIZE, DCI_DT_UINT64, DCIDESC_FILE_SIZE },
379 { _T("File.Time.Access(*)"), H_FileTime, (TCHAR *)FILETIME_ATIME, DCI_DT_UINT64, DCIDESC_FILE_TIME_ACCESS },
380 { _T("File.Time.Change(*)"), H_FileTime, (TCHAR *)FILETIME_CTIME, DCI_DT_UINT64, DCIDESC_FILE_TIME_CHANGE },
381 { _T("File.Time.Modify(*)"), H_FileTime, (TCHAR *)FILETIME_MTIME, DCI_DT_UINT64, DCIDESC_FILE_TIME_MODIFY },
382 { _T("Net.Resolver.AddressByName(*)"), H_ResolverAddrByName, NULL, DCI_DT_STRING, DCIDESC_NET_RESOLVER_ADDRBYNAME },
383 { _T("Net.Resolver.NameByAddress(*)"), H_ResolverNameByAddr, NULL, DCI_DT_STRING, DCIDESC_NET_RESOLVER_NAMEBYADDR },
384 { _T("System.CurrentTime"), H_SystemTime, NULL, DCI_DT_INT64, DCIDESC_SYSTEM_CURRENTTIME },
385 { _T("System.PlatformName"), H_PlatformName, NULL, DCI_DT_STRING, DCIDESC_SYSTEM_PLATFORMNAME }
386 };
387
388 /**
389 * Standard agent's lists
390 */
391 static NETXMS_SUBAGENT_LIST m_stdLists[] =
392 {
393 #ifdef _WIN32
394 { _T("FileSystem.MountPoints"), H_MountPoints, NULL },
395 #endif
396 { _T("Agent.ActionList"), H_ActionList, NULL },
397 { _T("Agent.SubAgentList"), H_SubAgentList, NULL },
398 { _T("Agent.SupportedLists"), H_EnumList, NULL },
399 { _T("Agent.SupportedParameters"), H_ParamList, NULL },
400 { _T("Agent.SupportedPushParameters"), H_PushParamList, NULL },
401 { _T("Agent.SupportedTables"), H_TableList, NULL },
402 { _T("Agent.ThreadPools"), H_ThreadPoolList, NULL }
403 };
404
405 /**
406 * Standard agent's tables
407 */
408 static NETXMS_SUBAGENT_TABLE m_stdTables[] =
409 {
410 { _T("Agent.SessionAgents"), H_SessionAgents, NULL, _T("SESSION_ID"), DCTDESC_AGENT_SUBAGENTS },
411 { _T("Agent.SubAgents"), H_SubAgentTable, NULL, _T("NAME"), DCTDESC_AGENT_SUBAGENTS },
412 #ifdef _WIN32
413 { _T("FileSystem.Volumes"), H_FileSystems, NULL, _T("VOLUME"), DCTDESC_FILESYSTEM_VOLUMES }
414 #endif
415 };
416
417 /**
418 * Initialize dynamic parameters list from default static list
419 */
420 BOOL InitParameterList()
421 {
422 if ((m_pParamList != NULL) || (m_pEnumList != NULL) || (m_pTableList != NULL))
423 return FALSE;
424
425 m_iNumParams = sizeof(m_stdParams) / sizeof(NETXMS_SUBAGENT_PARAM);
426 if (m_iNumParams > 0)
427 {
428 m_pParamList = (NETXMS_SUBAGENT_PARAM *)malloc(sizeof(NETXMS_SUBAGENT_PARAM) * m_iNumParams);
429 if (m_pParamList == NULL)
430 return FALSE;
431 memcpy(m_pParamList, m_stdParams, sizeof(NETXMS_SUBAGENT_PARAM) * m_iNumParams);
432 }
433
434 m_iNumEnums = sizeof(m_stdLists) / sizeof(NETXMS_SUBAGENT_LIST);
435 if (m_iNumEnums > 0)
436 {
437 m_pEnumList = (NETXMS_SUBAGENT_LIST *)malloc(sizeof(NETXMS_SUBAGENT_LIST) * m_iNumEnums);
438 if (m_pEnumList == NULL)
439 return FALSE;
440 memcpy(m_pEnumList, m_stdLists, sizeof(NETXMS_SUBAGENT_LIST) * m_iNumEnums);
441 }
442
443 m_iNumTables = sizeof(m_stdTables) / sizeof(NETXMS_SUBAGENT_TABLE);
444 if (m_iNumTables > 0)
445 {
446 m_pTableList = (NETXMS_SUBAGENT_TABLE *)malloc(sizeof(NETXMS_SUBAGENT_TABLE) * m_iNumTables);
447 if (m_pTableList == NULL)
448 return FALSE;
449 memcpy(m_pTableList, m_stdTables, sizeof(NETXMS_SUBAGENT_TABLE) * m_iNumTables);
450 }
451
452 return TRUE;
453 }
454
455 /**
456 * Add push parameter to list
457 * by LWX
458 */
459 void AddPushParameter(const TCHAR *name, int dataType, const TCHAR *description)
460 {
461 int i;
462
463 // Search for existing parameter
464 for(i = 0; i < m_iNumPushParams; i++)
465 if (!_tcsicmp(m_pPushParamList[i].name, name))
466 break;
467 if (i < m_iNumPushParams)
468 {
469 // Replace existing attributes
470 m_pPushParamList[i].dataType = dataType;
471 nx_strncpy(m_pPushParamList[i].description, description, MAX_DB_STRING);
472 }
473 else
474 {
475 // Add new parameter
476 m_pPushParamList = (NETXMS_SUBAGENT_PUSHPARAM *)realloc(m_pPushParamList, sizeof(NETXMS_SUBAGENT_PUSHPARAM) * (m_iNumPushParams + 1));
477 nx_strncpy(m_pPushParamList[m_iNumPushParams].name, name, MAX_PARAM_NAME - 1);
478 m_pPushParamList[m_iNumPushParams].dataType = dataType;
479 nx_strncpy(m_pPushParamList[m_iNumPushParams].description, description, MAX_DB_STRING);
480 m_iNumPushParams++;
481 }
482 }
483
484 /**
485 * Add parameter to list
486 */
487 void AddParameter(const TCHAR *pszName, LONG (* fpHandler)(const TCHAR *, const TCHAR *, TCHAR *, AbstractCommSession *), const TCHAR *pArg,
488 int iDataType, const TCHAR *pszDescription)
489 {
490 int i;
491
492 // Search for existing parameter
493 for(i = 0; i < m_iNumParams; i++)
494 if (!_tcsicmp(m_pParamList[i].name, pszName))
495 break;
496 if (i < m_iNumParams)
497 {
498 // Replace existing handler and attributes
499 m_pParamList[i].handler = fpHandler;
500 m_pParamList[i].dataType = iDataType;
501 nx_strncpy(m_pParamList[i].description, pszDescription, MAX_DB_STRING);
502
503 // If we are replacing System.PlatformName, add pointer to
504 // platform suffix as argument, otherwise, use supplied pArg
505 if (!_tcscmp(pszName, _T("System.PlatformName")))
506 {
507 m_pParamList[i].arg = g_szPlatformSuffix; // to be TCHAR
508 }
509 else
510 {
511 m_pParamList[i].arg = pArg;
512 }
513 }
514 else
515 {
516 // Add new parameter
517 m_pParamList = (NETXMS_SUBAGENT_PARAM *)realloc(m_pParamList, sizeof(NETXMS_SUBAGENT_PARAM) * (m_iNumParams + 1));
518 nx_strncpy(m_pParamList[m_iNumParams].name, pszName, MAX_PARAM_NAME - 1);
519 m_pParamList[m_iNumParams].handler = fpHandler;
520 m_pParamList[m_iNumParams].arg = pArg;
521 m_pParamList[m_iNumParams].dataType = iDataType;
522 nx_strncpy(m_pParamList[m_iNumParams].description, pszDescription, MAX_DB_STRING);
523 m_iNumParams++;
524 }
525 }
526
527 /**
528 * Add list
529 */
530 void AddList(const TCHAR *name, LONG (* handler)(const TCHAR *, const TCHAR *, StringList *, AbstractCommSession *), const TCHAR *arg)
531 {
532 int i;
533
534 // Search for existing enum
535 for(i = 0; i < m_iNumEnums; i++)
536 if (!_tcsicmp(m_pEnumList[i].name, name))
537 break;
538 if (i < m_iNumEnums)
539 {
540 // Replace existing handler and arg
541 m_pEnumList[i].handler = handler;
542 m_pEnumList[i].arg = arg;
543 }
544 else
545 {
546 // Add new enum
547 m_pEnumList = (NETXMS_SUBAGENT_LIST *)realloc(m_pEnumList, sizeof(NETXMS_SUBAGENT_LIST) * (m_iNumEnums + 1));
548 nx_strncpy(m_pEnumList[m_iNumEnums].name, name, MAX_PARAM_NAME - 1);
549 m_pEnumList[m_iNumEnums].handler = handler;
550 m_pEnumList[m_iNumEnums].arg = arg;
551 m_iNumEnums++;
552 }
553 }
554
555 /**
556 * Add table
557 */
558 void AddTable(const TCHAR *name, LONG (* handler)(const TCHAR *, const TCHAR *, Table *, AbstractCommSession *), const TCHAR *arg,
559 const TCHAR *instanceColumns, const TCHAR *description, int numColumns, NETXMS_SUBAGENT_TABLE_COLUMN *columns)
560 {
561 int i;
562
563 // Search for existing table
564 for(i = 0; i < m_iNumTables; i++)
565 if (!_tcsicmp(m_pTableList[i].name, name))
566 break;
567 if (i < m_iNumTables)
568 {
569 // Replace existing handler and arg
570 m_pTableList[i].handler = handler;
571 m_pTableList[i].arg = arg;
572 nx_strncpy(m_pTableList[m_iNumTables].instanceColumns, instanceColumns, MAX_COLUMN_NAME * MAX_INSTANCE_COLUMNS);
573 nx_strncpy(m_pTableList[m_iNumTables].description, description, MAX_DB_STRING);
574 m_pTableList[i].numColumns = numColumns;
575 m_pTableList[i].columns = columns;
576 }
577 else
578 {
579 // Add new table
580 m_pTableList = (NETXMS_SUBAGENT_TABLE *)realloc(m_pTableList, sizeof(NETXMS_SUBAGENT_TABLE) * (m_iNumTables + 1));
581 nx_strncpy(m_pTableList[m_iNumTables].name, name, MAX_PARAM_NAME);
582 m_pTableList[m_iNumTables].handler = handler;
583 m_pTableList[m_iNumTables].arg = arg;
584 nx_strncpy(m_pTableList[m_iNumTables].instanceColumns, instanceColumns, MAX_COLUMN_NAME * MAX_INSTANCE_COLUMNS);
585 nx_strncpy(m_pTableList[m_iNumTables].description, description, MAX_DB_STRING);
586 m_pTableList[m_iNumTables].numColumns = numColumns;
587 m_pTableList[m_iNumTables].columns = columns;
588 m_iNumTables++;
589 }
590 }
591
592 /**
593 * Add external parameter or list
594 */
595 bool AddExternalParameter(TCHAR *config, bool shellExec, bool isList)
596 {
597 TCHAR *cmdLine = _tcschr(config, _T(':'));
598 if (cmdLine == NULL)
599 return false;
600
601 *cmdLine = 0;
602 cmdLine++;
603 Trim(config);
604 Trim(cmdLine);
605 if ((*config == 0) || (*cmdLine == 0))
606 return false;
607
608 TCHAR *arg = (TCHAR *)malloc((_tcslen(cmdLine) + 2) * sizeof(TCHAR));
609 arg[0] = shellExec ? _T('S') : _T('E');
610 _tcscpy(&arg[1], cmdLine);
611 if (isList)
612 {
613 AddList(config, H_ExternalList, arg);
614 }
615 else
616 {
617 AddParameter(config, H_ExternalParameter, arg, DCI_DT_STRING, _T(""));
618 }
619 return true;
620 }
621
622 /**
623 * Add external table
624 */
625 bool AddExternalTable(TCHAR *config, bool shellExec)
626 {
627 TCHAR *options = _tcschr(config, _T(':'));
628 if (options == NULL)
629 return false;
630 *options = 0;
631 options++;
632
633 TCHAR *cmdLine = _tcschr(options, _T(':'));
634 if (cmdLine == NULL)
635 return false;
636 *cmdLine = 0;
637 cmdLine++;
638
639 Trim(config);
640 Trim(options);
641 Trim(cmdLine);
642 if ((*config == 0) || (*options == 0) || (*cmdLine == 0))
643 return false;
644
645 TCHAR instanceColumns[256] = _T("");
646 ExtractNamedOptionValue(options, _T("instanceColumns"), instanceColumns, 256);
647
648 TCHAR description[256] = _T("");
649 ExtractNamedOptionValue(options, _T("description"), description, 256);
650
651 TCHAR separator[16] = _T(",");
652 ExtractNamedOptionValue(options, _T("separator"), separator, 16);
653 if (separator[0] == _T('\\'))
654 {
655 switch(separator[1])
656 {
657 case 'n':
658 separator[0] = _T('\n');
659 break;
660 case 'r':
661 separator[0] = _T('\r');
662 break;
663 case 's':
664 separator[0] = _T(' ');
665 break;
666 case 't':
667 separator[0] = _T('\t');
668 break;
669 case 'u':
670 separator[0] = (TCHAR)_tcstoul(&separator[2], NULL, 10);
671 break;
672 }
673 }
674
675 TCHAR *arg = (TCHAR *)malloc((_tcslen(cmdLine) + 3) * sizeof(TCHAR));
676 arg[0] = separator[0];
677 arg[1] = shellExec ? _T('S') : _T('E');
678 _tcscpy(&arg[2], cmdLine);
679 AddTable(config, H_ExternalTable, arg, instanceColumns, description, 0, NULL);
680 return true;
681 }
682
683 /**
684 * Get parameter's value
685 */
686 UINT32 GetParameterValue(const TCHAR *param, TCHAR *value, AbstractCommSession *session)
687 {
688 int i, rc;
689 UINT32 dwErrorCode;
690
691 session->debugPrintf(5, _T("Requesting parameter \"%s\""), param);
692 for(i = 0; i < m_iNumParams; i++)
693 {
694 if (MatchString(m_pParamList[i].name, param, FALSE))
695 {
696 rc = m_pParamList[i].handler(param, m_pParamList[i].arg, value, session);
697 switch(rc)
698 {
699 case SYSINFO_RC_SUCCESS:
700 dwErrorCode = ERR_SUCCESS;
701 m_dwProcessedRequests++;
702 break;
703 case SYSINFO_RC_ERROR:
704 dwErrorCode = ERR_INTERNAL_ERROR;
705 m_dwFailedRequests++;
706 break;
707 case SYSINFO_RC_NO_SUCH_INSTANCE:
708 dwErrorCode = ERR_NO_SUCH_INSTANCE;
709 m_dwFailedRequests++;
710 break;
711 case SYSINFO_RC_UNSUPPORTED:
712 dwErrorCode = ERR_UNKNOWN_PARAMETER;
713 m_dwUnsupportedRequests++;
714 break;
715 default:
716 nxlog_write(MSG_UNEXPECTED_IRC, EVENTLOG_ERROR_TYPE, "ds", rc, param);
717 dwErrorCode = ERR_INTERNAL_ERROR;
718 m_dwFailedRequests++;
719 break;
720 }
721 break;
722 }
723 }
724
725 if (i == m_iNumParams)
726 {
727 rc = GetParameterValueFromExtProvider(param, value);
728 if (rc == SYSINFO_RC_SUCCESS)
729 {
730 dwErrorCode = ERR_SUCCESS;
731 m_dwProcessedRequests++;
732 }
733 else
734 {
735 dwErrorCode = ERR_UNKNOWN_PARAMETER;
736 }
737 }
738
739 if ((dwErrorCode == ERR_UNKNOWN_PARAMETER) && (i == m_iNumParams))
740 {
741 dwErrorCode = GetParameterValueFromAppAgent(param, value);
742 if (dwErrorCode == ERR_SUCCESS)
743 {
744 m_dwProcessedRequests++;
745 }
746 else if (dwErrorCode != ERR_UNKNOWN_PARAMETER)
747 {
748 m_dwFailedRequests++;
749 }
750 }
751
752 if ((dwErrorCode == ERR_UNKNOWN_PARAMETER) && (i == m_iNumParams))
753 {
754 dwErrorCode = GetParameterValueFromExtSubagent(param, value);
755 if (dwErrorCode == ERR_SUCCESS)
756 {
757 m_dwProcessedRequests++;
758 }
759 else if (dwErrorCode == ERR_UNKNOWN_PARAMETER)
760 {
761 m_dwUnsupportedRequests++;
762 }
763 else
764 {
765 m_dwFailedRequests++;
766 }
767 }
768
769 session->debugPrintf(7, _T("GetParameterValue(): result is %d (%s)"), (int)dwErrorCode,
770 dwErrorCode == ERR_SUCCESS ? _T("SUCCESS") : (dwErrorCode == ERR_UNKNOWN_PARAMETER ? _T("UNKNOWN_PARAMETER") : _T("INTERNAL_ERROR")));
771 return dwErrorCode;
772 }
773
774 /**
775 * Get list's value
776 */
777 UINT32 GetListValue(const TCHAR *param, StringList *value, AbstractCommSession *session)
778 {
779 int i, rc;
780 UINT32 dwErrorCode;
781
782 session->debugPrintf(5, _T("Requesting list \"%s\""), param);
783 for(i = 0; i < m_iNumEnums; i++)
784 {
785 if (MatchString(m_pEnumList[i].name, param, FALSE))
786 {
787 rc = m_pEnumList[i].handler(param, m_pEnumList[i].arg, value, session);
788 switch(rc)
789 {
790 case SYSINFO_RC_SUCCESS:
791 dwErrorCode = ERR_SUCCESS;
792 m_dwProcessedRequests++;
793 break;
794 case SYSINFO_RC_ERROR:
795 dwErrorCode = ERR_INTERNAL_ERROR;
796 m_dwFailedRequests++;
797 break;
798 case SYSINFO_RC_NO_SUCH_INSTANCE:
799 dwErrorCode = ERR_NO_SUCH_INSTANCE;
800 m_dwFailedRequests++;
801 break;
802 case SYSINFO_RC_UNSUPPORTED:
803 dwErrorCode = ERR_UNKNOWN_PARAMETER;
804 m_dwUnsupportedRequests++;
805 break;
806 default:
807 nxlog_write(MSG_UNEXPECTED_IRC, EVENTLOG_ERROR_TYPE, "ds", rc, param);
808 dwErrorCode = ERR_INTERNAL_ERROR;
809 m_dwFailedRequests++;
810 break;
811 }
812 break;
813 }
814 }
815
816 if (i == m_iNumEnums)
817 {
818 dwErrorCode = GetListValueFromExtSubagent(param, value);
819 if (dwErrorCode == ERR_SUCCESS)
820 {
821 m_dwProcessedRequests++;
822 }
823 else if (dwErrorCode == ERR_UNKNOWN_PARAMETER)
824 {
825 m_dwUnsupportedRequests++;
826 }
827 else
828 {
829 m_dwFailedRequests++;
830 }
831 }
832
833 session->debugPrintf(7, _T("GetListValue(): result is %d (%s)"), (int)dwErrorCode,
834 dwErrorCode == ERR_SUCCESS ? _T("SUCCESS") : (dwErrorCode == ERR_UNKNOWN_PARAMETER ? _T("UNKNOWN_PARAMETER") : _T("INTERNAL_ERROR")));
835 return dwErrorCode;
836 }
837
838 /**
839 * Get table's value
840 */
841 UINT32 GetTableValue(const TCHAR *param, Table *value, AbstractCommSession *session)
842 {
843 int i, rc;
844 UINT32 dwErrorCode;
845
846 session->debugPrintf(5, _T("Requesting table \"%s\""), param);
847 for(i = 0; i < m_iNumTables; i++)
848 {
849 if (MatchString(m_pTableList[i].name, param, FALSE))
850 {
851 // pre-fill table columns if specified in table definition
852 if (m_pTableList[i].numColumns > 0)
853 {
854 for(int c = 0; c < m_pTableList[i].numColumns; c++)
855 {
856 NETXMS_SUBAGENT_TABLE_COLUMN *col = &m_pTableList[i].columns[c];
857 value->addColumn(col->name, col->dataType, col->displayName, col->isInstance);
858 }
859 }
860
861 rc = m_pTableList[i].handler(param, m_pTableList[i].arg, value, session);
862 switch(rc)
863 {
864 case SYSINFO_RC_SUCCESS:
865 dwErrorCode = ERR_SUCCESS;
866 m_dwProcessedRequests++;
867 break;
868 case SYSINFO_RC_ERROR:
869 dwErrorCode = ERR_INTERNAL_ERROR;
870 m_dwFailedRequests++;
871 break;
872 case SYSINFO_RC_NO_SUCH_INSTANCE:
873 dwErrorCode = ERR_NO_SUCH_INSTANCE;
874 m_dwFailedRequests++;
875 break;
876 case SYSINFO_RC_UNSUPPORTED:
877 dwErrorCode = ERR_UNKNOWN_PARAMETER;
878 m_dwUnsupportedRequests++;
879 break;
880 default:
881 nxlog_write(MSG_UNEXPECTED_IRC, EVENTLOG_ERROR_TYPE, "ds", rc, param);
882 dwErrorCode = ERR_INTERNAL_ERROR;
883 m_dwFailedRequests++;
884 break;
885 }
886 break;
887 }
888 }
889
890 if (i == m_iNumTables)
891 {
892 dwErrorCode = GetTableValueFromExtSubagent(param, value);
893 if (dwErrorCode == ERR_SUCCESS)
894 {
895 m_dwProcessedRequests++;
896 }
897 else if (dwErrorCode == ERR_UNKNOWN_PARAMETER)
898 {
899 m_dwUnsupportedRequests++;
900 }
901 else
902 {
903 m_dwFailedRequests++;
904 }
905 }
906
907 session->debugPrintf(7, _T("GetTableValue(): result is %d (%s)"), (int)dwErrorCode,
908 dwErrorCode == ERR_SUCCESS ? _T("SUCCESS") : (dwErrorCode == ERR_UNKNOWN_PARAMETER ? _T("UNKNOWN_PARAMETER") : _T("INTERNAL_ERROR")));
909 return dwErrorCode;
910 }
911
912 /**
913 * Put complete list of supported parameters into NXCP message
914 */
915 void GetParameterList(NXCPMessage *pMsg)
916 {
917 int i;
918 UINT32 dwId, count;
919
920 // Parameters
921 for(i = 0, count = 0, dwId = VID_PARAM_LIST_BASE; i < m_iNumParams; i++)
922 {
923 if (m_pParamList[i].dataType != DCI_DT_DEPRECATED)
924 {
925 pMsg->setField(dwId++, m_pParamList[i].name);
926 pMsg->setField(dwId++, m_pParamList[i].description);
927 pMsg->setField(dwId++, (WORD)m_pParamList[i].dataType);
928 count++;
929 }
930 }
931 ListParametersFromExtProviders(pMsg, &dwId, &count);
932 ListParametersFromExtSubagents(pMsg, &dwId, &count);
933 pMsg->setField(VID_NUM_PARAMETERS, count);
934
935 // Push parameters
936 pMsg->setField(VID_NUM_PUSH_PARAMETERS, (UINT32)m_iNumPushParams);
937 for(i = 0, dwId = VID_PUSHPARAM_LIST_BASE; i < m_iNumPushParams; i++)
938 {
939 pMsg->setField(dwId++, m_pPushParamList[i].name);
940 pMsg->setField(dwId++, m_pPushParamList[i].description);
941 pMsg->setField(dwId++, (WORD)m_pPushParamList[i].dataType);
942 }
943
944 // Lists
945 pMsg->setField(VID_NUM_ENUMS, (UINT32)m_iNumEnums);
946 for(i = 0, dwId = VID_ENUM_LIST_BASE; i < m_iNumEnums; i++)
947 {
948 pMsg->setField(dwId++, m_pEnumList[i].name);
949 }
950 ListListsFromExtSubagents(pMsg, &dwId, &count);
951
952 // Tables
953 pMsg->setField(VID_NUM_TABLES, (UINT32)m_iNumTables);
954 for(i = 0, dwId = VID_TABLE_LIST_BASE; i < m_iNumTables; i++)
955 {
956 pMsg->setField(dwId++, m_pTableList[i].name);
957 pMsg->setField(dwId++, m_pTableList[i].instanceColumns);
958 pMsg->setField(dwId++, m_pTableList[i].description);
959 }
960 ListTablesFromExtSubagents(pMsg, &dwId, &count);
961 }
962
963 /**
964 * Put list of supported tables into NXCP message
965 */
966 void GetTableList(NXCPMessage *pMsg)
967 {
968 int i;
969 UINT32 dwId, count;
970
971 pMsg->setField(VID_NUM_TABLES, (UINT32)m_iNumTables);
972 for(i = 0, dwId = VID_TABLE_LIST_BASE; i < m_iNumTables; i++)
973 {
974 pMsg->setField(dwId++, m_pTableList[i].name);
975 pMsg->setField(dwId++, m_pTableList[i].instanceColumns);
976 pMsg->setField(dwId++, m_pTableList[i].description);
977 }
978 ListTablesFromExtSubagents(pMsg, &dwId, &count);
979 }
980
981 /**
982 * Put list of supported lists (enums) into NXCP message
983 */
984 void GetEnumList(NXCPMessage *pMsg)
985 {
986 int i;
987 UINT32 dwId, count;
988
989 pMsg->setField(VID_NUM_ENUMS, (UINT32)m_iNumEnums);
990 for(i = 0, dwId = VID_ENUM_LIST_BASE; i < m_iNumEnums; i++)
991 {
992 pMsg->setField(dwId++, m_pEnumList[i].name);
993 }
994 ListListsFromExtSubagents(pMsg, &dwId, &count);
995 }