Some descriptions changed
[public/netxms.git] / src / agent / core / getparam.cpp
1 /*
2 ** NetXMS multiplatform core agent
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: getparam.cpp
20 **
21 **/
22
23 #include "nxagentd.h"
24
25
26 //
27 // Externals
28 //
29
30 LONG H_AgentStats(char *cmd, char *arg, char *value);
31 LONG H_AgentUptime(char *cmd, char *arg, char *value);
32 LONG H_CRC32(char *cmd, char *arg, char *value);
33 LONG H_FileSize(char *cmd, char *arg, char *value);
34 LONG H_FileCount(char *pszCmd, char *pszArg, char *pValue);
35 LONG H_MD5Hash(char *cmd, char *arg, char *value);
36 LONG H_SHA1Hash(char *cmd, char *arg, char *value);
37 LONG H_SubAgentList(char *cmd, char *arg, NETXMS_VALUES_LIST *value);
38 LONG H_ActionList(char *cmd, char *arg, NETXMS_VALUES_LIST *value);
39 LONG H_ExternalParameter(char *pszCmd, char *pszArg, char *pValue);
40 LONG H_PlatformName(char *cmd, char *arg, char *value);
41
42 #ifdef _WIN32
43 LONG H_ArpCache(char *cmd, char *arg, NETXMS_VALUES_LIST *value);
44 LONG H_InterfaceList(char *cmd, char *arg, NETXMS_VALUES_LIST *value);
45 LONG H_ProcessList(char *cmd, char *arg, NETXMS_VALUES_LIST *value);
46 LONG H_ProcCount(char *cmd, char *arg, char *value);
47 LONG H_ProcCountSpecific(char *cmd, char *arg, char *value);
48 LONG H_ProcInfo(char *cmd, char *arg, char *value);
49 LONG H_DiskInfo(char *cmd, char *arg, char *value);
50 LONG H_MemoryInfo(char *cmd, char *arg, char *value);
51 LONG H_HostName(char *cmd, char *arg, char *value);
52 LONG H_SystemUname(char *cmd, char *arg, char *value);
53 LONG H_ThreadCount(char *cmd, char *arg, char *value);
54 LONG H_NetIPStats(char *cmd, char *arg, char *value);
55 LONG H_NetInterfaceStats(char *cmd, char *arg, char *value);
56 LONG H_ServiceState(char *cmd, char *arg, char *value);
57 LONG H_CPUCount(char *cmd, char *arg, char *value);
58 #endif
59
60
61 //
62 // Static data
63 //
64
65 static NETXMS_SUBAGENT_PARAM *m_pParamList = NULL;
66 static int m_iNumParams = 0;
67 static NETXMS_SUBAGENT_ENUM *m_pEnumList = NULL;
68 static int m_iNumEnums = 0;
69 static DWORD m_dwTimedOutRequests = 0;
70 static DWORD m_dwAuthenticationFailures = 0;
71 static DWORD m_dwProcessedRequests = 0;
72 static DWORD m_dwFailedRequests = 0;
73 static DWORD m_dwUnsupportedRequests = 0;
74
75
76 //
77 // Handler for parameters which always returns string constant
78 //
79
80 static LONG H_StringConstant(char *cmd, char *arg, char *value)
81 {
82 ret_string(value, arg);
83 return SYSINFO_RC_SUCCESS;
84 }
85
86
87 //
88 // Handler for parameters which returns floating point value from specific variable
89 //
90
91 static LONG H_FloatPtr(char *cmd, char *arg, char *value)
92 {
93 ret_double(value, *((double *)arg));
94 return SYSINFO_RC_SUCCESS;
95 }
96
97
98 //
99 // Handler for parameters which returns DWORD value from specific variable
100 //
101
102 static LONG H_UIntPtr(char *cmd, char *arg, char *value)
103 {
104 ret_uint(value, *((DWORD *)arg));
105 return SYSINFO_RC_SUCCESS;
106 }
107
108
109 //
110 // Handler for parameters list
111 //
112
113 static LONG H_ParamList(char *cmd, char *arg, NETXMS_VALUES_LIST *value)
114 {
115 int i;
116
117 for(i = 0; i < m_iNumParams; i++)
118 NxAddResultString(value, m_pParamList[i].szName);
119 return SYSINFO_RC_SUCCESS;
120 }
121
122
123 //
124 // Handler for enums list
125 //
126
127 static LONG H_EnumList(char *cmd, char *arg, NETXMS_VALUES_LIST *value)
128 {
129 int i;
130
131 for(i = 0; i < m_iNumEnums; i++)
132 NxAddResultString(value, m_pEnumList[i].szName);
133 return SYSINFO_RC_SUCCESS;
134 }
135
136
137 //
138 // Standard agent's parameters
139 //
140
141 static NETXMS_SUBAGENT_PARAM m_stdParams[] =
142 {
143 #ifdef _WIN32
144 { "Disk.Free(*)", H_DiskInfo, NULL, DCI_DT_UINT64, "Free disk space on *" },
145 { "Disk.Total(*)", H_DiskInfo, NULL, DCI_DT_UINT64, "Total disk space on *" },
146 { "Disk.Used(*)", H_DiskInfo, NULL, DCI_DT_UINT64, "Used disk space on *" },
147 { "Net.Interface.AdminStatus(*)", H_NetInterfaceStats, (char *)NET_IF_ADMIN_STATUS, DCI_DT_INT, "Administrative status of interface {instance}" },
148 { "Net.Interface.BytesIn(*)", H_NetInterfaceStats, (char *)NET_IF_BYTES_IN, DCI_DT_UINT, "Number of input bytes on interface {instance}" },
149 { "Net.Interface.BytesOut(*)", H_NetInterfaceStats, (char *)NET_IF_BYTES_OUT, DCI_DT_UINT, "Number of output bytes on interface {instance}" },
150 { "Net.Interface.Description(*)", H_NetInterfaceStats, (char *)NET_IF_DESCR, DCI_DT_STRING, "" },
151 { "Net.Interface.InErrors(*)", H_NetInterfaceStats, (char *)NET_IF_IN_ERRORS, DCI_DT_UINT, "Number of input errors on interface {instance}" },
152 { "Net.Interface.Link(*)", H_NetInterfaceStats, (char *)NET_IF_LINK, DCI_DT_INT, "Link status for interface {instance}" },
153 { "Net.Interface.OutErrors(*)", H_NetInterfaceStats, (char *)NET_IF_OUT_ERRORS, DCI_DT_UINT, "Number of output errors on interface {instance}" },
154 { "Net.Interface.PacketsIn(*)", H_NetInterfaceStats, (char *)NET_IF_PACKETS_IN, DCI_DT_UINT, "Number of input packets on interface {instance}" },
155 { "Net.Interface.PacketsOut(*)", H_NetInterfaceStats, (char *)NET_IF_PACKETS_OUT, DCI_DT_UINT, "Number of output packets on interface {instance}" },
156 { "Net.Interface.Speed(*)", H_NetInterfaceStats, (char *)NET_IF_SPEED, DCI_DT_UINT, "Speed of interface {instance}" },
157 { "Net.IP.Forwarding", H_NetIPStats, (char *)NET_IP_FORWARDING, DCI_DT_INT, "IP forwarding status" },
158 { "Process.Count(*)", H_ProcCountSpecific, NULL, DCI_DT_UINT, "" },
159 { "Process.GdiObj(*)", H_ProcInfo, (char *)PROCINFO_GDI_OBJ, DCI_DT_UINT64, "" },
160 { "Process.IO.OtherB(*)", H_ProcInfo, (char *)PROCINFO_IO_OTHER_B, DCI_DT_UINT64, "" },
161 { "Process.IO.OtherOp(*)", H_ProcInfo, (char *)PROCINFO_IO_OTHER_OP, DCI_DT_UINT64, "" },
162 { "Process.IO.ReadB(*)", H_ProcInfo, (char *)PROCINFO_IO_READ_B, DCI_DT_UINT64, "" },
163 { "Process.IO.ReadOp(*)", H_ProcInfo, (char *)PROCINFO_IO_READ_OP, DCI_DT_UINT64, "" },
164 { "Process.IO.WriteB(*)", H_ProcInfo, (char *)PROCINFO_IO_WRITE_B, DCI_DT_UINT64, "" },
165 { "Process.IO.WriteOp(*)", H_ProcInfo, (char *)PROCINFO_IO_WRITE_OP, DCI_DT_UINT64, "" },
166 { "Process.KernelTime(*)", H_ProcInfo, (char *)PROCINFO_KTIME, DCI_DT_UINT64, "" },
167 { "Process.PageFaults(*)", H_ProcInfo, (char *)PROCINFO_PF, DCI_DT_UINT64, "" },
168 { "Process.UserObj(*)", H_ProcInfo, (char *)PROCINFO_USER_OBJ, DCI_DT_UINT64, "" },
169 { "Process.UserTime(*)", H_ProcInfo, (char *)PROCINFO_UTIME, DCI_DT_UINT64, "" },
170 { "Process.VMSize(*)", H_ProcInfo, (char *)PROCINFO_VMSIZE, DCI_DT_UINT64, "" },
171 { "Process.WkSet(*)", H_ProcInfo, (char *)PROCINFO_WKSET, DCI_DT_UINT64, "" },
172 { "System.CPU.Count", H_CPUCount, NULL, DCI_DT_UINT, "Number of CPU in the system" },
173 { "System.Hostname", H_HostName, NULL, DCI_DT_STRING, "Host name" },
174 { "System.Memory.Physical.Free", H_MemoryInfo, (char *)MEMINFO_PHYSICAL_FREE, DCI_DT_UINT64, "Free physical memory" },
175 { "System.Memory.Physical.Total", H_MemoryInfo, (char *)MEMINFO_PHYSICAL_TOTAL, DCI_DT_UINT64, "Total amount of physical memory" },
176 { "System.Memory.Physical.Used", H_MemoryInfo, (char *)MEMINFO_PHYSICAL_USED, DCI_DT_UINT64, "Used physical memory" },
177 { "System.Memory.Swap.Free", H_MemoryInfo, (char *)MEMINFO_SWAP_FREE, DCI_DT_UINT64, "Free swap space" },
178 { "System.Memory.Swap.Total", H_MemoryInfo, (char *)MEMINFO_SWAP_TOTAL, DCI_DT_UINT64, "Total amount of swap space" },
179 { "System.Memory.Swap.Used", H_MemoryInfo, (char *)MEMINFO_SWAP_USED, DCI_DT_UINT64, "Used swap space" },
180 { "System.Memory.Virtual.Free", H_MemoryInfo, (char *)MEMINFO_VIRTUAL_FREE, DCI_DT_UINT64, "Free virtual memory" },
181 { "System.Memory.Virtual.Total", H_MemoryInfo, (char *)MEMINFO_VIRTUAL_TOTAL, DCI_DT_UINT64, "Total amount of virtual memory" },
182 { "System.Memory.Virtual.Used", H_MemoryInfo, (char *)MEMINFO_VIRTUAL_USED, DCI_DT_UINT64, "Used virtual memory" },
183 { "System.ProcessCount", H_ProcCount, NULL, DCI_DT_INT, "Total number of processes" },
184 { "System.ServiceState(*)", H_ServiceState, NULL, DCI_DT_INT, "State of {instance} service" },
185 { "System.ThreadCount", H_ThreadCount, NULL, DCI_DT_INT, "Total number of threads" },
186 { "System.Uname", H_SystemUname, NULL, DCI_DT_STRING, "System uname" },
187 #endif
188 { "Agent.AcceptedConnections", H_UIntPtr, (char *)&g_dwAcceptedConnections, DCI_DT_UINT, "" },
189 { "Agent.AcceptErrors", H_UIntPtr, (char *)&g_dwAcceptErrors, DCI_DT_UINT, "" },
190 { "Agent.AuthenticationFailures", H_UIntPtr, (char *)&m_dwAuthenticationFailures, DCI_DT_UINT, "" },
191 { "Agent.FailedRequests", H_UIntPtr, (char *)&m_dwFailedRequests, DCI_DT_UINT, "" },
192 { "Agent.ProcessedRequests", H_UIntPtr, (char *)&m_dwProcessedRequests, DCI_DT_UINT, "" },
193 { "Agent.RejectedConnections", H_UIntPtr, (char *)&g_dwRejectedConnections, DCI_DT_UINT, "" },
194 { "Agent.SourcePackageSupport", H_StringConstant, "0", DCI_DT_INT, "" },
195 { "Agent.TimedOutRequests", H_UIntPtr, (char *)&m_dwTimedOutRequests, DCI_DT_UINT, "" },
196 { "Agent.UnsupportedRequests", H_UIntPtr, (char *)&m_dwUnsupportedRequests, DCI_DT_UINT, "" },
197 { "Agent.Uptime", H_AgentUptime, NULL, DCI_DT_UINT, "Agent's uptime" },
198 { "Agent.Version", H_StringConstant, AGENT_VERSION_STRING, DCI_DT_STRING, "Agent's version" },
199 { "File.Count(*)", H_FileCount, NULL, DCI_DT_UINT, "" },
200 { "File.Hash.CRC32(*)", H_CRC32, NULL, DCI_DT_UINT, "CRC32 checksum of *" },
201 { "File.Hash.MD5(*)", H_MD5Hash, NULL, DCI_DT_STRING, "MD5 has of *" },
202 { "File.Hash.SHA1(*)", H_SHA1Hash, NULL, DCI_DT_STRING, "SHA1 hash of *" },
203 { "File.Size(*)", H_FileSize, NULL, DCI_DT_UINT64, "" },
204 { "System.PlatformName", H_PlatformName, NULL, DCI_DT_STRING, "" }
205 };
206
207
208 //
209 // Standard agent's enumerations
210 //
211
212 static NETXMS_SUBAGENT_ENUM m_stdEnums[] =
213 {
214 #ifdef _WIN32
215 { "Net.ArpCache", H_ArpCache, NULL },
216 { "Net.InterfaceList", H_InterfaceList, NULL },
217 { "System.ProcessList", H_ProcessList, NULL },
218 #endif
219 { "Agent.ActionList", H_ActionList, NULL },
220 { "Agent.SubAgentList", H_SubAgentList, NULL },
221 { "Agent.SupportedEnums", H_EnumList, NULL },
222 { "Agent.SupportedParameters", H_ParamList, NULL }
223 };
224
225
226 //
227 // Initialize dynamic parameters list from default static list
228 //
229
230 BOOL InitParameterList(void)
231 {
232 if ((m_pParamList != NULL) || (m_pEnumList != NULL))
233 return FALSE;
234
235 m_iNumParams = sizeof(m_stdParams) / sizeof(NETXMS_SUBAGENT_PARAM);
236 m_pParamList = (NETXMS_SUBAGENT_PARAM *)malloc(sizeof(NETXMS_SUBAGENT_PARAM) * m_iNumParams);
237 if (m_pParamList == NULL)
238 return FALSE;
239 memcpy(m_pParamList, m_stdParams, sizeof(NETXMS_SUBAGENT_PARAM) * m_iNumParams);
240
241 m_iNumEnums = sizeof(m_stdEnums) / sizeof(NETXMS_SUBAGENT_ENUM);
242 m_pEnumList = (NETXMS_SUBAGENT_ENUM *)malloc(sizeof(NETXMS_SUBAGENT_ENUM) * m_iNumEnums);
243 if (m_pEnumList == NULL)
244 return FALSE;
245 memcpy(m_pEnumList, m_stdEnums, sizeof(NETXMS_SUBAGENT_ENUM) * m_iNumEnums);
246
247 return TRUE;
248 }
249
250
251 //
252 // Add parameter to list
253 //
254
255 void AddParameter(char *pszName, LONG (* fpHandler)(char *,char *,char *), char *pArg,
256 int iDataType, char *pszDescription)
257 {
258 int i;
259
260 // Search for existing parameter
261 for(i = 0; i < m_iNumParams; i++)
262 if (!stricmp(m_pParamList[i].szName, pszName))
263 break;
264 if (i < m_iNumParams)
265 {
266 // Replace existing handler and attributes
267 m_pParamList[i].fpHandler = fpHandler;
268 m_pParamList[i].iDataType = iDataType;
269 strncpy(m_pParamList[i].szDescription, pszDescription, MAX_DB_STRING);
270
271 // If we are replacing System.PlatformName, add pointer to
272 // platform suffix as argument, otherwise, use supplied pArg
273 if (!strcmp(pszName, "System.PlatformName"))
274 {
275 m_pParamList[i].pArg = g_szPlatformSuffix;
276 }
277 else
278 {
279 m_pParamList[i].pArg = pArg;
280 }
281 }
282 else
283 {
284 // Add new parameter
285 m_pParamList = (NETXMS_SUBAGENT_PARAM *)realloc(m_pParamList, sizeof(NETXMS_SUBAGENT_PARAM) * (m_iNumParams + 1));
286 strncpy(m_pParamList[m_iNumParams].szName, pszName, MAX_PARAM_NAME - 1);
287 m_pParamList[m_iNumParams].fpHandler = fpHandler;
288 m_pParamList[m_iNumParams].pArg = pArg;
289 m_pParamList[m_iNumParams].iDataType = iDataType;
290 strncpy(m_pParamList[m_iNumParams].szDescription, pszDescription, MAX_DB_STRING);
291 m_iNumParams++;
292 }
293 }
294
295
296 //
297 // Add enum to list
298 //
299
300 void AddEnum(char *pszName, LONG (* fpHandler)(char *,char *,NETXMS_VALUES_LIST *), char *pArg)
301 {
302 int i;
303
304 // Search for existing enum
305 for(i = 0; i < m_iNumEnums; i++)
306 if (!stricmp(m_pEnumList[i].szName, pszName))
307 break;
308 if (i < m_iNumEnums)
309 {
310 // Replace existing handler and arg
311 m_pEnumList[i].fpHandler = fpHandler;
312 m_pEnumList[i].pArg = pArg;
313 }
314 else
315 {
316 // Add new enum
317 m_pEnumList = (NETXMS_SUBAGENT_ENUM *)realloc(m_pEnumList, sizeof(NETXMS_SUBAGENT_ENUM) * (m_iNumEnums + 1));
318 strncpy(m_pEnumList[m_iNumEnums].szName, pszName, MAX_PARAM_NAME - 1);
319 m_pEnumList[m_iNumEnums].fpHandler = fpHandler;
320 m_pEnumList[m_iNumEnums].pArg = pArg;
321 m_iNumEnums++;
322 }
323 }
324
325
326 //
327 // Add external parameter
328 //
329
330 BOOL AddExternalParameter(char *pszCfgLine)
331 {
332 char *pszCmdLine;
333
334 pszCmdLine = strchr(pszCfgLine, ':');
335 if (pszCmdLine == NULL)
336 return FALSE;
337
338 *pszCmdLine = 0;
339 pszCmdLine++;
340 StrStrip(pszCfgLine);
341 StrStrip(pszCmdLine);
342 if ((*pszCfgLine == 0) || (*pszCmdLine == 0))
343 return FALSE;
344
345 AddParameter(pszCfgLine, H_ExternalParameter, strdup(pszCmdLine), DCI_DT_STRING, "");
346 return TRUE;
347 }
348
349
350 //
351 // Get parameter's value
352 //
353
354 DWORD GetParameterValue(char *pszParam, char *pszValue)
355 {
356 int i, rc;
357 DWORD dwErrorCode;
358
359 DebugPrintf("Requesting parameter \"%s\"", pszParam);
360 for(i = 0; i < m_iNumParams; i++)
361 if (MatchString(m_pParamList[i].szName, pszParam, FALSE))
362 {
363 rc = m_pParamList[i].fpHandler(pszParam, m_pParamList[i].pArg, pszValue);
364 switch(rc)
365 {
366 case SYSINFO_RC_SUCCESS:
367 dwErrorCode = ERR_SUCCESS;
368 m_dwProcessedRequests++;
369 break;
370 case SYSINFO_RC_ERROR:
371 dwErrorCode = ERR_INTERNAL_ERROR;
372 m_dwFailedRequests++;
373 break;
374 case SYSINFO_RC_UNSUPPORTED:
375 dwErrorCode = ERR_UNKNOWN_PARAMETER;
376 m_dwUnsupportedRequests++;
377 break;
378 default:
379 WriteLog(MSG_UNEXPECTED_IRC, EVENTLOG_ERROR_TYPE, "ds", rc, pszParam);
380 dwErrorCode = ERR_INTERNAL_ERROR;
381 m_dwFailedRequests++;
382 break;
383 }
384 break;
385 }
386 if (i == m_iNumParams)
387 {
388 dwErrorCode = ERR_UNKNOWN_PARAMETER;
389 m_dwUnsupportedRequests++;
390 }
391 return dwErrorCode;
392 }
393
394
395 //
396 // Get parameter's value
397 //
398
399 DWORD GetEnumValue(char *pszParam, NETXMS_VALUES_LIST *pValue)
400 {
401 int i, rc;
402 DWORD dwErrorCode;
403
404 DebugPrintf("Requesting enum \"%s\"", pszParam);
405 for(i = 0; i < m_iNumEnums; i++)
406 if (MatchString(m_pEnumList[i].szName, pszParam, FALSE))
407 {
408 rc = m_pEnumList[i].fpHandler(pszParam, m_pEnumList[i].pArg, pValue);
409 switch(rc)
410 {
411 case SYSINFO_RC_SUCCESS:
412 dwErrorCode = ERR_SUCCESS;
413 m_dwProcessedRequests++;
414 break;
415 case SYSINFO_RC_ERROR:
416 dwErrorCode = ERR_INTERNAL_ERROR;
417 m_dwFailedRequests++;
418 break;
419 case SYSINFO_RC_UNSUPPORTED:
420 dwErrorCode = ERR_UNKNOWN_PARAMETER;
421 m_dwUnsupportedRequests++;
422 break;
423 default:
424 WriteLog(MSG_UNEXPECTED_IRC, EVENTLOG_ERROR_TYPE, "ds", rc, pszParam);
425 dwErrorCode = ERR_INTERNAL_ERROR;
426 m_dwFailedRequests++;
427 break;
428 }
429 break;
430 }
431 if (i == m_iNumEnums)
432 {
433 dwErrorCode = ERR_UNKNOWN_PARAMETER;
434 m_dwUnsupportedRequests++;
435 }
436 return dwErrorCode;
437 }
438
439
440 //
441 // Put complete list of supported parameters into CSCP message
442 //
443
444 void GetParameterList(CSCPMessage *pMsg)
445 {
446 int i;
447 DWORD dwId;
448
449 pMsg->SetVariable(VID_NUM_PARAMETERS, (DWORD)m_iNumParams);
450 for(i = 0, dwId = VID_PARAM_LIST_BASE; i < m_iNumParams; i++)
451 {
452 pMsg->SetVariable(dwId++, m_pParamList[i].szName);
453 pMsg->SetVariable(dwId++, m_pParamList[i].szDescription);
454 pMsg->SetVariable(dwId++, (WORD)m_pParamList[i].iDataType);
455 }
456 }