option to set individual types for each varbind in nxsnmpset; added Eclipse project...
[public/netxms.git] / src / snmp / nxsnmpset / nxsnmpset.cpp
1 /*
2 ** nxsnmpset - command line tool used to set parameters on SNMP agent
3 ** Copyright (C) 2004-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: nxsnmpset.cpp
20 **
21 **/
22
23 #include <nms_common.h>
24 #include <nms_agent.h>
25 #include <nms_util.h>
26 #include <nxsnmp.h>
27
28
29 //
30 // Static data
31 //
32
33 static char m_community[256] = "public";
34 static char m_user[256] = "";
35 static char m_authPassword[256] = "";
36 static char m_encryptionPassword[256] = "";
37 static int m_authMethod = SNMP_AUTH_NONE;
38 static int m_encryptionMethod = SNMP_ENCRYPT_NONE;
39 static UINT16 m_port = 161;
40 static UINT32 m_snmpVersion = SNMP_VERSION_2C;
41 static UINT32 m_timeout = 3000;
42 static UINT32 m_type = ASN_OCTET_STRING;
43
44 /**
45 * Set variables
46 */
47 static int SetVariables(int argc, TCHAR *argv[])
48 {
49 SNMP_UDPTransport *pTransport;
50 SNMP_PDU *request, *response;
51 SNMP_Variable *pVar;
52 DWORD dwResult;
53 int i, iExit = 0;
54
55 // Initialize WinSock
56 #ifdef _WIN32
57 WSADATA wsaData;
58 WSAStartup(2, &wsaData);
59 #endif
60
61 // Create SNMP transport
62 pTransport = new SNMP_UDPTransport;
63 dwResult = pTransport->createUDPTransport(argv[0], m_port);
64 if (dwResult != SNMP_ERR_SUCCESS)
65 {
66 _tprintf(_T("Unable to create UDP transport: %s\n"), SNMPGetErrorText(dwResult));
67 iExit = 2;
68 }
69 else
70 {
71 pTransport->setSnmpVersion(m_snmpVersion);
72 if (m_snmpVersion == SNMP_VERSION_3)
73 pTransport->setSecurityContext(new SNMP_SecurityContext(m_user, m_authPassword, m_encryptionPassword, m_authMethod, m_encryptionMethod));
74 else
75 pTransport->setSecurityContext(new SNMP_SecurityContext(m_community));
76
77 // Create request
78 request = new SNMP_PDU(SNMP_SET_REQUEST, getpid(), m_snmpVersion);
79 for(i = 1; i < argc; i += 2)
80 {
81 TCHAR *p = _tcschr(argv[i], _T('@'));
82 UINT32 type = m_type;
83 if (p != NULL)
84 {
85 *p = 0;
86 p++;
87 type = SNMPResolveDataType(p);
88 if (type == ASN_NULL)
89 {
90 _tprintf(_T("Invalid data type: %s\n"), p);
91 iExit = 5;
92 }
93 }
94 if (SNMPIsCorrectOID(argv[i]))
95 {
96 pVar = new SNMP_Variable(argv[i]);
97 pVar->setValueFromString(type, argv[i + 1]);
98 request->bindVariable(pVar);
99 }
100 else
101 {
102 _tprintf(_T("Invalid OID: %s\n"), argv[i]);
103 iExit = 4;
104 }
105 }
106
107 // Send request and process response
108 if (iExit == 0)
109 {
110 if ((dwResult = pTransport->doRequest(request, &response, m_timeout, 3)) == SNMP_ERR_SUCCESS)
111 {
112 if (response->getErrorCode() != 0)
113 {
114 _tprintf(_T("SET operation failed (error code %d)\n"), response->getErrorCode());
115 }
116 delete response;
117 }
118 else
119 {
120 _tprintf(_T("%s\n"), SNMPGetErrorText(dwResult));
121 iExit = 3;
122 }
123 }
124
125 delete request;
126 }
127
128 delete pTransport;
129 return iExit;
130 }
131
132 /**
133 * Startup
134 */
135 int main(int argc, char *argv[])
136 {
137 int ch, iExit = 1;
138 DWORD dwValue;
139 char *eptr;
140 BOOL bStart = TRUE;
141
142 InitNetXMSProcess();
143
144 // Parse command line
145 opterr = 1;
146 while((ch = getopt(argc, argv, "a:A:c:e:E:hp:t:u:v:w:")) != -1)
147 {
148 switch(ch)
149 {
150 case 'h': // Display help and exit
151 _tprintf(_T("Usage: nxsnmpset [<options>] <host> <variable>[@<type>] <value>\n")
152 _T("Valid options are:\n")
153 _T(" -a <method> : Authentication method for SNMP v3 USM. Valid methods are MD5 and SHA1\n")
154 _T(" -A <passwd> : User's authentication password for SNMP v3 USM\n")
155 _T(" -c <string> : Community string. Default is \"public\"\n")
156 _T(" -e <method> : Encryption method for SNMP v3 USM. Valid methods are DES and AES\n")
157 _T(" -E <passwd> : User's encryption password for SNMP v3 USM\n")
158 _T(" -h : Display help and exit\n")
159 _T(" -p <port> : Agent's port number. Default is 161\n")
160 _T(" -t <type> : Specify variable's data type. Default is octet string.\n")
161 _T(" -u <user> : User name for SNMP v3 USM\n")
162 _T(" -v <version> : SNMP version to use (valid values is 1, 2c, and 3)\n")
163 _T(" -w <seconds> : Request timeout (default is 3 seconds)\n")
164 _T("Note: You can specify data type either as number or in symbolic form.\n")
165 _T(" Valid symbolic representations are following:\n")
166 _T(" INTEGER, STRING, OID, IPADDR, COUNTER32, GAUGE32,\n")
167 _T(" TIMETICKS, COUNTER64, UINT32.\n")
168 _T("\n"));
169 iExit = 0;
170 bStart = FALSE;
171 break;
172 case 't':
173 // First, check for numeric representation
174 dwValue = strtoul(optarg, &eptr, 0);
175 if (*eptr != 0)
176 {
177 // Try to resolve from symbolic form
178 #ifdef UNICODE
179 WCHAR *wdt = WideStringFromMBString(optarg);
180 dwValue = SNMPResolveDataType(wdt);
181 free(wdt);
182 #else
183 dwValue = SNMPResolveDataType(optarg);
184 #endif
185 if (dwValue == ASN_NULL)
186 {
187 _tprintf(_T("Invalid data type %hs\n"), optarg);
188 bStart = FALSE;
189 }
190 else
191 {
192 m_type = dwValue;
193 }
194 }
195 else
196 {
197 m_type = dwValue;
198 }
199 break;
200 case 'c': // Community
201 strncpy(m_community, optarg, 256);
202 m_community[255] = 0;
203 break;
204 case 'u': // User
205 strncpy(m_user, optarg, 256);
206 m_user[255] = 0;
207 break;
208 case 'a': // authentication method
209 if (!stricmp(optarg, "md5"))
210 {
211 m_authMethod = SNMP_AUTH_MD5;
212 }
213 else if (!stricmp(optarg, "sha1"))
214 {
215 m_authMethod = SNMP_AUTH_SHA1;
216 }
217 else if (!stricmp(optarg, "none"))
218 {
219 m_authMethod = SNMP_AUTH_NONE;
220 }
221 else
222 {
223 _tprintf(_T("Invalid authentication method %hs\n"), optarg);
224 bStart = FALSE;
225 }
226 break;
227 case 'A': // authentication password
228 strncpy(m_authPassword, optarg, 256);
229 m_authPassword[255] = 0;
230 if (strlen(m_authPassword) < 8)
231 {
232 _tprintf(_T("Authentication password should be at least 8 characters long\n"));
233 bStart = FALSE;
234 }
235 break;
236 case 'e': // encryption method
237 if (!stricmp(optarg, "des"))
238 {
239 m_encryptionMethod = SNMP_ENCRYPT_DES;
240 }
241 else if (!stricmp(optarg, "aes"))
242 {
243 m_encryptionMethod = SNMP_ENCRYPT_AES;
244 }
245 else if (!stricmp(optarg, "none"))
246 {
247 m_encryptionMethod = SNMP_ENCRYPT_NONE;
248 }
249 else
250 {
251 _tprintf(_T("Invalid encryption method %hs\n"), optarg);
252 bStart = FALSE;
253 }
254 break;
255 case 'E': // encription password
256 strncpy(m_encryptionPassword, optarg, 256);
257 m_encryptionPassword[255] = 0;
258 if (strlen(m_encryptionPassword) < 8)
259 {
260 _tprintf(_T("Encryption password should be at least 8 characters long\n"));
261 bStart = FALSE;
262 }
263 break;
264 case 'p': // Port number
265 dwValue = strtoul(optarg, &eptr, 0);
266 if ((*eptr != 0) || (dwValue > 65535) || (dwValue == 0))
267 {
268 _tprintf(_T("Invalid port number %hs\n"), optarg);
269 bStart = FALSE;
270 }
271 else
272 {
273 m_port = (WORD)dwValue;
274 }
275 break;
276 case 'v': // Version
277 if (!strcmp(optarg, "1"))
278 {
279 m_snmpVersion = SNMP_VERSION_1;
280 }
281 else if (!stricmp(optarg, "2c"))
282 {
283 m_snmpVersion = SNMP_VERSION_2C;
284 }
285 else if (!stricmp(optarg, "3"))
286 {
287 m_snmpVersion = SNMP_VERSION_3;
288 }
289 else
290 {
291 _tprintf(_T("Invalid SNMP version %hs\n"), optarg);
292 bStart = FALSE;
293 }
294 break;
295 case 'w': // Timeout
296 dwValue = strtoul(optarg, &eptr, 0);
297 if ((*eptr != 0) || (dwValue > 60) || (dwValue == 0))
298 {
299 _tprintf(_T("Invalid timeout value %hs\n"), optarg);
300 bStart = FALSE;
301 }
302 else
303 {
304 m_timeout = dwValue;
305 }
306 break;
307 case '?':
308 bStart = FALSE;
309 break;
310 default:
311 break;
312 }
313 }
314
315 if (bStart)
316 {
317 if (argc - optind < 3)
318 {
319 _tprintf(_T("Required argument(s) missing.\nUse nxsnmpset -h to get complete command line syntax.\n"));
320 }
321 else if ((argc - optind) % 2 != 1)
322 {
323 _tprintf(_T("Missing value for variable.\nUse nxsnmpset -h to get complete command line syntax.\n"));
324 }
325 else
326 {
327 #ifdef UNICODE
328 WCHAR *wargv[256];
329 for(int i = optind; i < argc; i++)
330 wargv[i - optind] = WideStringFromMBString(argv[i]);
331 iExit = SetVariables(argc - optind, wargv);
332 for(int i = 0; i < argc - optind; i++)
333 free(wargv[i]);
334 #else
335 iExit = SetVariables(argc - optind, &argv[optind]);
336 #endif
337 }
338 }
339
340 return iExit;
341 }