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