2 * snmptest.c - send snmp requests to a network entity.
4 * Usage: snmptest -v 1 [-q] hostname community [objectID]
7 /***********************************************************************
8 Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
12 Permission to use, copy, modify, and distribute this software and its
13 documentation for any purpose and without fee is hereby granted,
14 provided that the above copyright notice appear in all copies and that
15 both that copyright notice and this permission notice appear in
16 supporting documentation, and that the name of CMU not be
17 used in advertising or publicity pertaining to distribution of the
18 software without specific, written prior permission.
20 CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
21 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
22 CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
23 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
24 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
25 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
27 ******************************************************************/
28 #include <net-snmp/net-snmp-config.h>
41 #include <sys/types.h>
43 #include <netinet/in.h>
47 #if TIME_WITH_SYS_TIME
49 # include <sys/timeb.h>
51 # include <sys/time.h>
56 # include <sys/time.h>
62 #include <sys/select.h>
71 #include <arpa/inet.h>
74 #include <net-snmp/net-snmp-includes.h>
76 int command = SNMP_MSG_GET;
78 int input_variable(netsnmp_variable_list *);
83 fprintf(stderr, "USAGE: snmptest ");
84 snmp_parse_args_usage(stderr);
85 fprintf(stderr, "\n\n");
86 snmp_parse_args_descriptions(stderr);
90 main(int argc, char *argv[])
92 netsnmp_session session, *ss;
93 netsnmp_pdu *pdu = NULL, *response, *copy = NULL;
94 netsnmp_variable_list *vars, *vp;
95 netsnmp_transport *transport = NULL;
99 int varcount, nonRepeaters = -1, maxRepetitions;
102 * get the common command line arguments
104 switch (snmp_parse_args(argc, argv, &session, NULL, NULL)) {
117 * open an SNMP session
119 ss = snmp_open(&session);
122 * diagnose snmp_open errors with the input netsnmp_session pointer
124 snmp_sess_perror("snmptest", &session);
132 for (ret = 1; ret != 0;) {
133 vp = (netsnmp_variable_list *)
134 malloc(sizeof(netsnmp_variable_list));
135 memset(vp, 0, sizeof(netsnmp_variable_list));
137 while ((ret = input_variable(vp)) == -1);
147 pdu = snmp_pdu_create(command);
150 vars->next_variable = vp;
155 * free the last (unused) variable
158 free((char *) vp->name);
160 free((char *) vp->val.string);
163 if (command == SNMP_MSG_GETBULK) {
164 if (nonRepeaters == -1) {
165 nonRepeaters = varcount;
166 ret = -1; /* so we collect more variables */
167 printf("Now input the repeating variables\n");
169 printf("What repeat count? ");
171 fgets(input, sizeof(input), stdin);
172 maxRepetitions = atoi(input);
173 pdu->non_repeaters = nonRepeaters;
174 pdu->max_repetitions = maxRepetitions;
178 if (varcount == 0 && ret == 0) {
180 printf("No PDU to send.\n");
183 pdu = snmp_clone_pdu(copy);
184 printf("Resending last PDU.\n");
188 copy = snmp_clone_pdu(pdu);
189 if (command == SNMP_MSG_TRAP2) {
193 if (!snmp_send(ss, pdu)) {
195 snmp_sess_perror("snmptest", ss);
198 status = snmp_synch_response(ss, pdu, &response);
199 if (status == STAT_SUCCESS) {
200 if (command == SNMP_MSG_INFORM &&
201 response->errstat == SNMP_ERR_NOERROR) {
202 printf("Inform Acknowledged\n");
204 switch (response->command) {
206 printf("Received Get Request ");
208 case SNMP_MSG_GETNEXT:
209 printf("Received Getnext Request ");
211 case SNMP_MSG_RESPONSE:
212 printf("Received Get Response ");
215 printf("Received Set Request ");
218 printf("Received Trap Request ");
220 case SNMP_MSG_GETBULK:
221 printf("Received Bulk Request ");
223 case SNMP_MSG_INFORM:
224 printf("Received Inform Request ");
227 printf("Received SNMPv2 Trap Request ");
230 transport = snmp_sess_transport(snmp_sess_pointer(ss));
231 if (transport != NULL && transport->f_fmtaddr != NULL) {
232 char *s = transport->f_fmtaddr(transport,
236 transport_data_length);
237 printf("from %s\n", s);
239 printf("from <UNKNOWN>\n");
242 ("requestid 0x%lX errstat 0x%lX errindex 0x%lX\n",
243 response->reqid, response->errstat,
245 if (response->errstat == SNMP_ERR_NOERROR) {
246 for (vars = response->variables; vars;
247 vars = vars->next_variable)
248 print_variable(vars->name, vars->name_length,
251 printf("Error in packet.\nReason: %s\n",
252 snmp_errstring(response->errstat));
253 if (response->errindex != 0) {
254 for (count = 1, vars = response->variables;
255 vars && count != response->errindex;
256 vars = vars->next_variable, count++);
258 printf("Failed object: ");
259 print_objid(vars->name, vars->name_length);
265 } else if (status == STAT_TIMEOUT) {
266 printf("Timeout: No Response from %s\n", session.peername);
267 } else { /* status == STAT_ERROR */
268 snmp_sess_perror("snmptest", ss);
272 snmp_free_pdu(response);
282 input_variable(netsnmp_variable_list * vp)
286 u_char value[256], ch;
287 oid name[MAX_OID_LEN];
289 printf("Variable: ");
291 if (!fgets(buf, sizeof(buf), stdin)) {
292 printf("Quitting, Goobye\n");
296 val_len = strlen(buf);
298 if (val_len == 0 || *buf == '\n') {
302 if (buf[val_len - 1] == '\n')
305 switch (toupper(buf[1])) {
307 command = SNMP_MSG_GET;
308 printf("Request type is Get Request\n");
311 command = SNMP_MSG_GETNEXT;
312 printf("Request type is Getnext Request\n");
315 command = SNMP_MSG_SET;
316 printf("Request type is Set Request\n");
319 command = SNMP_MSG_GETBULK;
320 printf("Request type is Bulk Request\n");
322 ("Enter a blank line to terminate the list of non-repeaters\n");
323 printf("and to begin the repeating variables\n");
326 command = SNMP_MSG_INFORM;
327 printf("Request type is Inform Request\n");
328 printf("(Are you sending to the right port?)\n");
331 command = SNMP_MSG_TRAP2;
332 printf("Request type is SNMPv2 Trap Request\n");
333 printf("(Are you sending to the right port?)\n");
336 if (snmp_get_dump_packet()) {
337 snmp_set_dump_packet(0);
338 printf("Turned packet dump off\n");
340 snmp_set_dump_packet(1);
341 printf("Turned packet dump on\n");
345 switch ((toupper(buf[2]))) {
348 printf("Quitting, Goodbye\n");
353 if (snmp_get_quick_print()) {
354 snmp_set_quick_print(0);
355 printf("Turned quick printing off\n");
357 snmp_set_quick_print(1);
358 printf("Turned quick printing on\n");
364 printf("Bad command\n");
368 vp->name_length = MAX_OID_LEN;
369 if (!snmp_parse_oid(buf, name, &vp->name_length)) {
373 vp->name = (oid *) malloc(vp->name_length * sizeof(oid));
374 memmove(vp->name, name, vp->name_length * sizeof(oid));
376 if (command == SNMP_MSG_SET || command == SNMP_MSG_INFORM
377 || command == SNMP_MSG_TRAP2) {
378 printf("Type [i|u|s|x|d|n|o|t|a]: ");
380 fgets(buf, sizeof(buf), stdin);
384 vp->type = ASN_INTEGER;
387 vp->type = ASN_UNSIGNED;
390 vp->type = ASN_OCTET_STR;
393 vp->type = ASN_OCTET_STR;
396 vp->type = ASN_OCTET_STR;
402 vp->type = ASN_OBJECT_ID;
405 vp->type = ASN_TIMETICKS;
408 vp->type = ASN_IPADDRESS;
412 ("bad type \"%c\", use \"i\", \"u\", \"s\", \"x\", \"d\", \"n\", \"o\", \"t\", or \"a\".\n",
419 fgets(buf, sizeof(buf), stdin);
422 vp->val.integer = (long *) malloc(sizeof(long));
423 *(vp->val.integer) = atoi(buf);
424 vp->val_len = sizeof(long);
427 vp->val.integer = (long *) malloc(sizeof(long));
428 *(vp->val.integer) = strtoul(buf, NULL, 0);
429 vp->val_len = sizeof(long);
433 size_t buf_len = 256;
435 if ((vp->val.string = (u_char *) malloc(buf_len)) == NULL) {
436 printf("malloc failure\n");
439 if (!snmp_decimal_to_binary(&(vp->val.string), &buf_len,
441 printf("Bad value or no sub-identifier > 255\n");
442 free(vp->val.string);
445 vp->val_len = val_len;
446 } else if (ch == 's') {
448 * -1 to omit trailing newline
450 vp->val.string = (u_char *) malloc(strlen(buf) - 1);
451 if (vp->val.string == NULL) {
452 printf("malloc failure\n");
455 memcpy(vp->val.string, buf, strlen(buf) - 1);
456 vp->val_len = strlen(buf) - 1;
457 } else if (ch == 'x') {
458 size_t buf_len = 256;
460 if ((vp->val.string = (u_char *) malloc(buf_len)) == NULL) {
461 printf("malloc failure\n");
464 if (!snmp_hex_to_binary(&(vp->val.string), &buf_len,
466 printf("Bad value (need pairs of hex digits)\n");
467 free(vp->val.string);
470 vp->val_len = val_len;
475 vp->val.string = NULL;
478 if ('\n' == buf[strlen(buf) - 1])
479 buf[strlen(buf) - 1] = '\0';
480 vp->val_len = MAX_OID_LEN;;
481 read_objid(buf, (oid *) value, &vp->val_len);
482 vp->val_len *= sizeof(oid);
483 vp->val.objid = (oid *) malloc(vp->val_len);
484 memmove(vp->val.objid, value, vp->val_len);
487 vp->val.integer = (long *) malloc(sizeof(long));
488 *(vp->val.integer) = atoi(buf);
489 vp->val_len = sizeof(long);
492 vp->val.integer = (long *) malloc(sizeof(long));
493 *(vp->val.integer) = inet_addr(buf);
494 vp->val_len = sizeof(long);
497 printf("Internal error\n");
500 } else { /* some form of get message */