snmptest.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:17k
- /*
- * snmptest.c - send snmp requests to a network entity.
- *
- * Usage: snmptest -v 1 [-q] hostname community [objectID]
- *
- */
- /***********************************************************************
- Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
- All Rights Reserved
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted,
- provided that the above copyright notice appear in all copies and that
- both that copyright notice and this permission notice appear in
- supporting documentation, and that the name of CMU not be
- used in advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
- CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- SOFTWARE.
- ******************************************************************/
- #include <net-snmp/net-snmp-config.h>
- #if HAVE_STDLIB_H
- #include <stdlib.h>
- #endif
- #if HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #if HAVE_STRING_H
- #include <string.h>
- #else
- #include <strings.h>
- #endif
- #include <sys/types.h>
- #if HAVE_NETINET_IN_H
- #include <netinet/in.h>
- #endif
- #include <stdio.h>
- #include <ctype.h>
- #if TIME_WITH_SYS_TIME
- # ifdef WIN32
- # include <sys/timeb.h>
- # else
- # include <sys/time.h>
- # endif
- # include <time.h>
- #else
- # if HAVE_SYS_TIME_H
- # include <sys/time.h>
- # else
- # include <time.h>
- # endif
- #endif
- #if HAVE_SYS_SELECT_H
- #include <sys/select.h>
- #endif
- #if HAVE_WINSOCK_H
- #include <winsock.h>
- #endif
- #if HAVE_NETDB_H
- #include <netdb.h>
- #endif
- #if HAVE_ARPA_INET_H
- #include <arpa/inet.h>
- #endif
- #include <net-snmp/net-snmp-includes.h>
- int command = SNMP_MSG_GET;
- int input_variable(netsnmp_variable_list *);
- void
- usage(void)
- {
- fprintf(stderr, "USAGE: snmptest ");
- snmp_parse_args_usage(stderr);
- fprintf(stderr, "nn");
- snmp_parse_args_descriptions(stderr);
- }
- int
- main(int argc, char *argv[])
- {
- netsnmp_session session, *ss;
- netsnmp_pdu *pdu = NULL, *response, *copy = NULL;
- netsnmp_variable_list *vars, *vp;
- netsnmp_transport *transport = NULL;
- int ret;
- int status, count;
- char input[128];
- int varcount, nonRepeaters = -1, maxRepetitions;
- /*
- * get the common command line arguments
- */
- switch (snmp_parse_args(argc, argv, &session, NULL, NULL)) {
- case -2:
- exit(0);
- case -1:
- usage();
- exit(1);
- default:
- break;
- }
- SOCK_STARTUP;
- /*
- * open an SNMP session
- */
- ss = snmp_open(&session);
- if (ss == NULL) {
- /*
- * diagnose snmp_open errors with the input netsnmp_session pointer
- */
- snmp_sess_perror("snmptest", &session);
- SOCK_CLEANUP;
- exit(1);
- }
- varcount = 0;
- while (1) {
- vars = NULL;
- for (ret = 1; ret != 0;) {
- vp = (netsnmp_variable_list *)
- malloc(sizeof(netsnmp_variable_list));
- memset(vp, 0, sizeof(netsnmp_variable_list));
- while ((ret = input_variable(vp)) == -1);
- if (ret == 1) {
- varcount++;
- /*
- * add it to the list
- */
- if (vars == NULL) {
- /*
- * if first variable
- */
- pdu = snmp_pdu_create(command);
- pdu->variables = vp;
- } else {
- vars->next_variable = vp;
- }
- vars = vp;
- } else {
- /*
- * free the last (unused) variable
- */
- if (vp->name)
- free((char *) vp->name);
- if (vp->val.string)
- free((char *) vp->val.string);
- free((char *) vp);
- if (command == SNMP_MSG_GETBULK) {
- if (nonRepeaters == -1) {
- nonRepeaters = varcount;
- ret = -1; /* so we collect more variables */
- printf("Now input the repeating variablesn");
- } else {
- printf("What repeat count? ");
- fflush(stdout);
- fgets(input, sizeof(input), stdin);
- maxRepetitions = atoi(input);
- pdu->non_repeaters = nonRepeaters;
- pdu->max_repetitions = maxRepetitions;
- }
- }
- }
- if (varcount == 0 && ret == 0) {
- if (!copy) {
- printf("No PDU to send.n");
- ret = -1;
- } else {
- pdu = snmp_clone_pdu(copy);
- printf("Resending last PDU.n");
- }
- }
- }
- copy = snmp_clone_pdu(pdu);
- if (command == SNMP_MSG_TRAP2) {
- /*
- * No response needed
- */
- if (!snmp_send(ss, pdu)) {
- snmp_free_pdu(pdu);
- snmp_sess_perror("snmptest", ss);
- }
- } else {
- status = snmp_synch_response(ss, pdu, &response);
- if (status == STAT_SUCCESS) {
- if (command == SNMP_MSG_INFORM &&
- response->errstat == SNMP_ERR_NOERROR) {
- printf("Inform Acknowledgedn");
- } else {
- switch (response->command) {
- case SNMP_MSG_GET:
- printf("Received Get Request ");
- break;
- case SNMP_MSG_GETNEXT:
- printf("Received Getnext Request ");
- break;
- case SNMP_MSG_RESPONSE:
- printf("Received Get Response ");
- break;
- case SNMP_MSG_SET:
- printf("Received Set Request ");
- break;
- case SNMP_MSG_TRAP:
- printf("Received Trap Request ");
- break;
- case SNMP_MSG_GETBULK:
- printf("Received Bulk Request ");
- break;
- case SNMP_MSG_INFORM:
- printf("Received Inform Request ");
- break;
- case SNMP_MSG_TRAP2:
- printf("Received SNMPv2 Trap Request ");
- break;
- }
- transport = snmp_sess_transport(snmp_sess_pointer(ss));
- if (transport != NULL && transport->f_fmtaddr != NULL) {
- char *addr_string = transport->f_fmtaddr(transport,
- response->
- transport_data,
- response->
- transport_data_length);
- if (addr_string != NULL) {
- printf("from %sn", addr_string);
- free(addr_string);
- }
- } else {
- printf("from <UNKNOWN>n");
- }
- printf
- ("requestid 0x%lX errstat 0x%lX errindex 0x%lXn",
- response->reqid, response->errstat,
- response->errindex);
- if (response->errstat == SNMP_ERR_NOERROR) {
- for (vars = response->variables; vars;
- vars = vars->next_variable)
- print_variable(vars->name, vars->name_length,
- vars);
- } else {
- printf("Error in packet.nReason: %sn",
- snmp_errstring(response->errstat));
- if (response->errindex != 0) {
- for (count = 1, vars = response->variables;
- vars && count != response->errindex;
- vars = vars->next_variable, count++);
- if (vars) {
- printf("Failed object: ");
- print_objid(vars->name, vars->name_length);
- }
- printf("n");
- }
- }
- }
- } else if (status == STAT_TIMEOUT) {
- printf("Timeout: No Response from %sn", session.peername);
- } else { /* status == STAT_ERROR */
- snmp_sess_perror("snmptest", ss);
- }
- if (response)
- snmp_free_pdu(response);
- }
- varcount = 0;
- nonRepeaters = -1;
- }
- SOCK_CLEANUP;
- return 0;
- }
- int
- input_variable(netsnmp_variable_list * vp)
- {
- char buf[256];
- size_t val_len;
- u_char value[256], ch;
- oid name[MAX_OID_LEN];
- printf("Variable: ");
- fflush(stdout);
- if (!fgets(buf, sizeof(buf), stdin)) {
- printf("Quitting, Goobyen");
- SOCK_CLEANUP;
- exit(0);
- }
- val_len = strlen(buf);
- if (val_len == 0 || *buf == 'n') {
- vp->name_length = 0;
- return 0;
- }
- if (buf[val_len - 1] == 'n')
- buf[--val_len] = 0;
- if (*buf == '$') {
- switch (toupper(buf[1])) {
- case 'G':
- command = SNMP_MSG_GET;
- printf("Request type is Get Requestn");
- break;
- case 'N':
- command = SNMP_MSG_GETNEXT;
- printf("Request type is Getnext Requestn");
- break;
- case 'S':
- command = SNMP_MSG_SET;
- printf("Request type is Set Requestn");
- break;
- case 'B':
- command = SNMP_MSG_GETBULK;
- printf("Request type is Bulk Requestn");
- printf
- ("Enter a blank line to terminate the list of non-repeatersn");
- printf("and to begin the repeating variablesn");
- break;
- case 'I':
- command = SNMP_MSG_INFORM;
- printf("Request type is Inform Requestn");
- printf("(Are you sending to the right port?)n");
- break;
- case 'T':
- command = SNMP_MSG_TRAP2;
- printf("Request type is SNMPv2 Trap Requestn");
- printf("(Are you sending to the right port?)n");
- break;
- case 'D':
- if (snmp_get_dump_packet()) {
- snmp_set_dump_packet(0);
- printf("Turned packet dump offn");
- } else {
- snmp_set_dump_packet(1);
- printf("Turned packet dump onn");
- }
- break;
- case 'Q':
- switch ((toupper(buf[2]))) {
- case 'n':
- case 0:
- printf("Quitting, Goodbyen");
- SOCK_CLEANUP;
- exit(0);
- break;
- case 'P':
- if (snmp_get_quick_print()) {
- snmp_set_quick_print(0);
- printf("Turned quick printing offn");
- } else {
- snmp_set_quick_print(1);
- printf("Turned quick printing onn");
- }
- break;
- }
- break;
- default:
- printf("Bad commandn");
- }
- return -1;
- }
- vp->name_length = MAX_OID_LEN;
- if (!snmp_parse_oid(buf, name, &vp->name_length)) {
- snmp_perror(buf);
- return -1;
- }
- vp->name = (oid *) malloc(vp->name_length * sizeof(oid));
- memmove(vp->name, name, vp->name_length * sizeof(oid));
- if (command == SNMP_MSG_SET || command == SNMP_MSG_INFORM
- || command == SNMP_MSG_TRAP2) {
- printf("Type [i|u|s|x|d|n|o|t|a]: ");
- fflush(stdout);
- fgets(buf, sizeof(buf), stdin);
- ch = *buf;
- switch (ch) {
- case 'i':
- vp->type = ASN_INTEGER;
- break;
- case 'u':
- vp->type = ASN_UNSIGNED;
- break;
- case 's':
- vp->type = ASN_OCTET_STR;
- break;
- case 'x':
- vp->type = ASN_OCTET_STR;
- break;
- case 'd':
- vp->type = ASN_OCTET_STR;
- break;
- case 'n':
- vp->type = ASN_NULL;
- break;
- case 'o':
- vp->type = ASN_OBJECT_ID;
- break;
- case 't':
- vp->type = ASN_TIMETICKS;
- break;
- case 'a':
- vp->type = ASN_IPADDRESS;
- break;
- default:
- printf
- ("bad type "%c", use "i", "u", "s", "x", "d", "n", "o", "t", or "a".n",
- *buf);
- return -1;
- }
- getValue:
- printf("Value: ");
- fflush(stdout);
- fgets(buf, sizeof(buf), stdin);
- switch (vp->type) {
- case ASN_INTEGER:
- vp->val.integer = (long *) malloc(sizeof(long));
- *(vp->val.integer) = atoi(buf);
- vp->val_len = sizeof(long);
- break;
- case ASN_UNSIGNED:
- vp->val.integer = (long *) malloc(sizeof(long));
- *(vp->val.integer) = strtoul(buf, NULL, 0);
- vp->val_len = sizeof(long);
- break;
- case ASN_OCTET_STR:
- if (ch == 'd') {
- size_t buf_len = 256;
- val_len = 0;
- if ((vp->val.string = (u_char *) malloc(buf_len)) == NULL) {
- printf("malloc failuren");
- goto getValue;
- }
- if (!snmp_decimal_to_binary(&(vp->val.string), &buf_len,
- &val_len, 1, buf)) {
- printf("Bad value or no sub-identifier > 255n");
- free(vp->val.string);
- goto getValue;
- }
- vp->val_len = val_len;
- } else if (ch == 's') {
- /*
- * -1 to omit trailing newline
- */
- vp->val.string = (u_char *) malloc(strlen(buf) - 1);
- if (vp->val.string == NULL) {
- printf("malloc failuren");
- goto getValue;
- }
- memcpy(vp->val.string, buf, strlen(buf) - 1);
- vp->val_len = strlen(buf) - 1;
- } else if (ch == 'x') {
- size_t buf_len = 256;
- val_len = 0;
- if ((vp->val.string = (u_char *) malloc(buf_len)) == NULL) {
- printf("malloc failuren");
- goto getValue;
- }
- if (!snmp_hex_to_binary(&(vp->val.string), &buf_len,
- &val_len, 1, buf)) {
- printf("Bad value (need pairs of hex digits)n");
- free(vp->val.string);
- goto getValue;
- }
- vp->val_len = val_len;
- }
- break;
- case ASN_NULL:
- vp->val_len = 0;
- vp->val.string = NULL;
- break;
- case ASN_OBJECT_ID:
- if ('n' == buf[strlen(buf) - 1])
- buf[strlen(buf) - 1] = ' ';
- vp->val_len = MAX_OID_LEN;;
- read_objid(buf, (oid *) value, &vp->val_len);
- vp->val_len *= sizeof(oid);
- vp->val.objid = (oid *) malloc(vp->val_len);
- memmove(vp->val.objid, value, vp->val_len);
- break;
- case ASN_TIMETICKS:
- vp->val.integer = (long *) malloc(sizeof(long));
- *(vp->val.integer) = atoi(buf);
- vp->val_len = sizeof(long);
- break;
- case ASN_IPADDRESS:
- vp->val.integer = (long *) malloc(sizeof(long));
- *(vp->val.integer) = inet_addr(buf);
- vp->val_len = sizeof(long);
- break;
- default:
- printf("Internal errorn");
- break;
- }
- } else { /* some form of get message */
- vp->type = ASN_NULL;
- vp->val_len = 0;
- }
- return 1;
- }