📄 snmpint.c
字号:
#include <wrn/wm/snmp/engine/buffer.h>#include <wrn/wm/snmp/engine/objectid.h>#include <wrn/wm/snmp/engine/snmp.h>#include <wrn/wm/snmp/engine/snmpstat.h>#include <wrn/wm/snmp/engine/auxfuncs.h>#include <wrn/wm/snmp/engine/buildpkt.h>#include <wrn/wm/snmp/engine/wkobj.h>#include "md.h"#include "snmpint.h"#include "mibutils.h"#include "nprint.h"#include <wrn/wm/demo/snarklib.h>#include <wrn/wm/demo/snmpfunc.h>#include <wrn/wm/demo/snmpconf.h>#include <wrn/wm/common/glue.h>INT_32_T snmpSetSerialNo;#define OIDSZ(oid) (sizeof(oid)/sizeof(OIDC_T))#if (ENVOY_NEED_STATS)SNMP_STATS_T snmp_stats;#endifenum help_level { help_none, help_short, help_long };/********************************************************************** * Some SNMP agents seem to have trouble with the GET NEXT SNMP * function. These agents seem to have trouble finding the next from * an arbitrary object identifier. Consequently, an alternative * starting point is defined which corresponds to the first variable * in the standard internet MIB, "sysDescr". **********************************************************************/#if defined(RIGHT_WAY)OIDC_T default_base_oid[] = {0, 0};#else /* WRONG WAY -- but compatable anyway */OIDC_T default_base_oid[] = {1, 3, 6, 1, 2, 1, 1, 1}; /* sysDescr */#endifunsigned int req_id = 0;extern alt_display;#if sartestchar snmp_get_request_community[256] = "public";char snmp_set_request_community[256] = "private";#endif /*sartest*/static char *snmp_errors[] = { "no error", "too big", "no such name", "bad value", "read only", "general error", "no access", "wrong type", "wrong length", "wrong encoding", "wrong value", "no creation", "inconsistent value", "resource unavailable", "commit failed", "undo failed", "authorization error", "not writable", "inconsistent name" };static char *snmp_alt_errors[] = { "noError","tooBig","noSuchName","badValue","readOnly", "genError","noAccess","wrongType","wrongLength", "wrongEncoding","wrongValue","noCreation","inconsistentValue", "resourceUnavailable","commitFailed","undoFailed", "authorizationError","notWritable","inconsistentName"};#define SNMP_ERRORS_SIZE (sizeof(snmp_errors)/sizeof(snmp_errors[0]))static char snmp_errors_flags[SNMP_ERRORS_SIZE] ={ 0, 0, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1 };/* A structure to keep state during asynchronous operations while setting * up for doing a set. */struct set_op { int argc; char **argv; int count; OIDC_T val_oid[40]; int val_len; SNMP_PKT_T *pkt; int oid_len; OIDC_T oid_buf[40]; UINT_32_T high; UINT_32_T low; OCTET_T bstring[20]; struct sty *sty;};/* Internal function declarations */static void parse_set_args __((struct set_op *));static void parse_tset_args __((struct set_op *)); static void error_response(struct sty *sty, char *error_msg){ if (batch_mode) sty_putc(sty, '|'); sty_printf(sty, "%s\n", error_msg); command_next(sty);}/* Prints out an SNMP packet received as a response. */static void response_print(struct sty *sty, SNMP_PKT_T *rcvd_pkt){ if (rcvd_pkt->pdu.std_pdu.error_status == NO_ERROR) print_pkt(sty, rcvd_pkt); else print_snmp_error(sty, rcvd_pkt); SNMP_Free(rcvd_pkt); command_next(sty);}/* Print out information about the error that came back. */void print_snmp_error(struct sty *sty, SNMP_PKT_T *pkt){if (batch_mode) sty_printf(sty, "\\Error %d Index %d\n", (int)pkt->pdu.std_pdu.error_status, (int)pkt->pdu.std_pdu.error_index);else { if (pkt->pdu.std_pdu.error_status < SNMP_ERRORS_SIZE) { if (alt_display) sty_printf(sty, "{%s}\n", snmp_alt_errors[(int)pkt->pdu.std_pdu.error_status]); else sty_printf(sty, "SNMP agent reports `%s'\n", snmp_errors[(int)pkt->pdu.std_pdu.error_status]); if (snmp_errors_flags[(int)pkt->pdu.std_pdu.error_status]) { sty_puts(sty, " "); if ((pkt->pdu.std_pdu.error_index > 0) && ((pkt->pdu.std_pdu.error_index - 1) < pkt->pdu.std_pdu.std_vbl.vbl_count)) print_vb(sty, &pkt->pdu.std_pdu.std_vbl.vblist[(int)pkt->pdu.std_pdu.error_index - 1]); else sty_printf(sty, "Error index %ld out of range\n", pkt->pdu.std_pdu.error_index); } } else sty_printf(sty, "Unknown SNMP error %ld\n", pkt->pdu.std_pdu.error_status); }}/* since md_hostname_to_addr doesn't take a cookie */static struct set_op *set_static;static void hostname_set_continue(struct sty *sty, char *hostname, ipaddr_t *hostaddr){ if ((hostaddr == 0) || (hostaddr->type != IPV4) || (*(bits32_t *)(&hostaddr->addr) == 0)) { if (batch_mode) sty_putc(sty, '|'); sty_printf(sty, "Can not locate host %s\n", set_static->argv[1]); SNMP_Free(set_static->pkt); free(set_static); command_next(sty); } else { SNMP_Bind_IP_Address(set_static->pkt, set_static->count /* index */, set_static->oid_len, set_static->oid_buf, (OCTET_T *)&(hostaddr->addr)); set_static->argc -= 2; set_static->argv += 2; set_static->count += 1; set_static->sty = sty; parse_set_args(set_static); /* continue building the set packet */ }}/* Parses the arguments to the SET command. */static void parse_set_args(struct set_op *set_state){ int type; char *err_msg; int SetValue; while (set_state->argc) { set_state->oid_len = string2oid(set_state->argv[0], set_state->oid_buf, sizeof(set_state->oid_buf)/sizeof(OIDC_T)); if (set_state->oid_len == 0) { if (batch_mode) sty_putc(set_state->sty, '|'); sty_printf(set_state->sty, "No mib entry `%s'\n", set_state->argv[0]); goto bug_out; } else if (set_state->oid_len > sizeof(set_state->oid_buf)/sizeof(OIDC_T)) { if (batch_mode) sty_putc(set_state->sty, '|'); sty_puts(set_state->sty, "Internal buffer exceeded, OID too long.\n"); goto bug_out; } type = oid_type(set_state->oid_buf, set_state->oid_len); switch (type) { case 0: if (batch_mode) sty_putc(set_state->sty, '|'); sty_printf(set_state->sty, "Don't know the variable type for %s. Try TSET instead\n", set_state->argv[0]); goto bug_out; case VT_NUMBER: if ( isdigit( *set_state->argv[ 1 ] ) ) { SNMP_Bind_Integer(set_state->pkt, set_state->count /* index */, set_state->oid_len, set_state->oid_buf, atol(set_state->argv[1])); } else { /* see if there's a leaf "argv[1]" below the target's node. */ SetValue = FindLeafValue(set_state->argv[1], set_state->oid_buf, set_state->oid_len); if (SetValue == -1) { if (batch_mode) sty_putc(set_state->sty, '|'); sty_printf(set_state->sty, "For mib variable `%s' no enumerated value `%s'.\n", set_state->argv[0], set_state->argv[1]); goto bug_out; } SNMP_Bind_Integer(set_state->pkt, set_state->count /* index */, set_state->oid_len, set_state->oid_buf, SetValue ); } break; case VT_STRING: if (!(alt_display || set_state->argv[1][0] == '#')) SNMP_Bind_String(set_state->pkt, set_state->count /* index */, set_state->oid_len, set_state->oid_buf, (OCTET_T)VT_STRING, STRLEN(set_state->argv[1]), (OCTET_T *)set_state->argv[1], 1 /* copy */); else { int oc_len; char oc_ptr[256]; char *dis_ptr = set_state->argv[1]; oc_len = strToOctet (dis_ptr, oc_ptr); SNMP_Bind_String(set_state->pkt, set_state->count /* index */, set_state->oid_len, set_state->oid_buf, (OCTET_T)VT_STRING, oc_len, (OCTET_T *)oc_ptr, 1 /* copy */); } break; case VT_IPADDRESS: set_static = set_state; md_hostname_to_addr(set_state->sty, set_state->argv[1], hostname_set_continue); return; case VT_COUNTER: case VT_GAUGE: case VT_TIMETICKS: SNMP_Bind_Unsigned_Integer(set_state->pkt, set_state->count /*index*/, set_state->oid_len, set_state->oid_buf, (OCTET_T)type, (UINT_32_T)atol(set_state->argv[1])); break; case VT_OBJECT: set_state->val_len = string2oid(set_state->argv[1], set_state->val_oid, sizeof(set_state->val_oid)/sizeof(OIDC_T)); if (set_state->val_len == 0) { if (batch_mode) sty_putc(set_state->sty, '|'); sty_printf(set_state->sty, "No mib entry `%s'\n", set_state->argv[1]); goto bug_out; } else if (set_state->val_len > sizeof(set_state->val_oid)/sizeof(OIDC_T)) { if (batch_mode) sty_putc(set_state->sty, '|'); sty_puts(set_state->sty, "Internal buffer exceeded, Value OID too long.\n"); goto bug_out; } SNMP_Bind_Object_ID(set_state->pkt, set_state->count /* index */, set_state->oid_len, set_state->oid_buf, set_state->val_len, set_state->val_oid); break; /* We can only use v2 types if they are installed */#if (ENVOY_USE_V2_TYPES) case VT_COUNTER64: if (sscanf(set_state->argv[1], "%ld:%ld", &(set_state->high), &(set_state->low)) != 2) { sty_puts(set_state->sty, "Counter 64 needs 2 arguments high:low\n"); goto bug_out; } SNMP_Bind_64_Unsigned_Integer(set_state->pkt, set_state->count, set_state->oid_len, set_state->oid_buf, (OCTET_T)VT_COUNTER64, set_state->high, set_state->low); break;#else /* (ENVOY_USE_V2_TYPES) */ /* If the version 2 types aren't installed, mention that to the user */ case VT_COUNTER64: if (batch_mode) sty_putc(set_state->sty, '|'); sty_puts(set_state->sty, "V2 type requested but v2 type code isn't installed\n"); goto bug_out;#endif /* (ENVOY_USE_V2_TYPES) */ default: case VT_EMPTY: case VT_OPAQUE: if (batch_mode) sty_putc(set_state->sty, '|'); sty_printf(set_state->sty, "unknown type %d\n", type); goto bug_out; } set_state->argc -= 2; set_state->argv += 2; set_state->count += 1; } err_msg = snmp_send_rec(set_state->sty, set_state->pkt, &dest_addr, response_print, error_response); if (err_msg != 0) { if (batch_mode) sty_putc(set_state->sty, '|'); sty_printf(set_state->sty, "%s\n", err_msg); command_next(set_state->sty); } else free(set_state); return; bug_out: SNMP_Free(set_state->pkt); free(set_state); command_next(set_state->sty);}/* * Implements the SET command. */boolean_t do_set(struct sty *sty, enum help_level help, int argc, char *argv[]){struct set_op *set_state;switch (help) { case help_short: sty_puts(sty, "\set <variable> <value> [<variable> <value>] ... - set MIB variables\n"); break; case help_long: sty_puts(sty, "\The 'set <variable> <value> [<variable> <value>] ...' command\n\does an SNMP SET of <variable> to <value>. <Value> will be interpreted\n\relative to the type of <variable> as found in the mib. If <variable> is\n\not in the mib then an error is reported (see tset).\n"); break; case help_none: if (dest_addr.type == IPNONE) { if (batch_mode) sty_putc(sty, '|'); sty_puts(sty, "Need to specify destination first.\n"); return 1; } if (argc < 3) { if (batch_mode) sty_putc(sty, '|'); sty_puts(sty, "Need to specify MIB variables to SET and values.\n"); return 1; } if ((argc & 1) == 0) { /* if argc is even */ if (batch_mode) sty_putc(sty, '|'); sty_puts(sty, "Need matching number of variables and values.\n"); return 1; } set_state = (struct set_op *)malloc(sizeof(struct set_op)); if (set_state == 0) { if (batch_mode) sty_putc(sty, '|'); sty_puts(sty, "No memory.\n"); return 1; } set_state->argc = argc - 1; set_state->argv = argv + 1; set_state->count = 0; set_state->sty = sty;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -