int agentx_register(netsnmp_session * ss, oid start[], size_t startlen, int priority, int range_subid, oid range_ubound, int timeout, u_char flags, const char *contextName) { netsnmp_pdu *pdu, *response; DEBUGMSGTL(("agentx/subagent", "registering: ")); DEBUGMSGOIDRANGE(("agentx/subagent", start, startlen, range_subid, range_ubound)); DEBUGMSG(("agentx/subagent", "\n")); if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) { return 0; } pdu = snmp_pdu_create(AGENTX_MSG_REGISTER); if (pdu == NULL) { return 0; } pdu->time = timeout; pdu->priority = priority; pdu->sessid = ss->sessid; pdu->range_subid = range_subid; if (contextName) { pdu->flags |= AGENTX_MSG_FLAG_NON_DEFAULT_CONTEXT; pdu->community = strdup(contextName); pdu->community_len = strlen(contextName); } if (flags & FULLY_QUALIFIED_INSTANCE) { pdu->flags |= AGENTX_MSG_FLAG_INSTANCE_REGISTER; } if (range_subid) { snmp_pdu_add_variable(pdu, start, startlen, ASN_OBJECT_ID, (u_char *) start, startlen * sizeof(oid)); pdu->variables->val.objid[range_subid - 1] = range_ubound; } else { snmp_add_null_var(pdu, start, startlen); } if (agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS) { DEBUGMSGTL(("agentx/subagent", "registering failed!\n")); return 0; } if (response->errstat != SNMP_ERR_NOERROR) { snmp_log(LOG_ERR,"registering pdu failed: %d!\n", response->errstat); snmp_free_pdu(response); return 0; } snmp_free_pdu(response); DEBUGMSGTL(("agentx/subagent", "registered\n")); return 1; }
/** Write on/off status */ double setMainSwitch(HSNMP m_sessp,float value) { struct snmp_pdu* pdu = snmp_pdu_create(SNMP_MSG_SET); // prepare set-request pdu pdu->community = (u_char*)strdup(writeCommunity); pdu->community_len = strlen(writeCommunity); // for(each SET request to one crate) { int v = (int) value; snmp_pdu_add_variable(pdu,oidSysMainSwitch,lengthSysMainSwitch,ASN_INTEGER,(u_char*)&v,sizeof(v)); // } // endfor struct snmp_pdu* response; int status = snmp_sess_synch_response(m_sessp,pdu,&response); /* * Process the response. */ if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) { /* * SUCCESS: Print the result variables */ struct variable_list *vars; // debug print //for(vars = response->variables; vars; vars = vars->next_variable) // print_variable(vars->name, vars->name_length, vars); /* manipuate the information ourselves */ for(vars = response->variables; vars; vars = vars->next_variable) { if (vars->type == ASN_OPAQUE_FLOAT) { // 0x78 value = *vars->val.floatVal; } else if (vars->type == ASN_OPAQUE_DOUBLE) { // 0x79 value = *vars->val.doubleVal; } else if(vars->type == ASN_INTEGER) { // 0x02 value = (double)*vars->val.integer; } } } else { /* * FAILURE: print what went wrong! */ if (status == STAT_SUCCESS) fprintf(stderr, "Error in packet\nReason: %s\n", snmp_errstring(response->errstat)); else snmp_sess_perror("snmpget",snmp_sess_session(m_sessp)); return 0; } snmp_free_pdu(response); return value; }
static inline void add_field ( netsnmp_pdu *trap_pdu, u_char asn_type, const char *prefix, void *value, size_t value_size) { oid _oid[MAX_OID_LEN]; size_t _oid_len = MAX_OID_LEN; if (snmp_parse_oid(prefix, _oid, &_oid_len)) { snmp_pdu_add_variable (trap_pdu, _oid, _oid_len, asn_type, (u_char *) value, value_size); } }
static void OpeningEntry(UNUSED tState self) { netsnmp_pdu* act = pdu_create_opt_context(AGENTX_MSG_OPEN, context, contextLen); if(act) { act->sessid = 0; act->transid = 0; act->reqid = ++packetid; act->time = 0; snmp_pdu_add_variable(act, NULL, 0, ASN_OCTET_STR, NULL, 0); if(snmp_sess_send(sessp, act) == 0) snmp_free_pdu(act); } }
int agentx_register( struct snmp_session *ss, oid start[], size_t startlen, int priority, int range_subid, oid range_ubound) { struct snmp_pdu *pdu, *response; DEBUGMSGTL(("agentx/subagent","registering: ")); DEBUGMSGOID(("agentx/subagent", start, startlen)); DEBUGMSG(("agentx/subagent","\n")); if (! IS_AGENTX_VERSION( ss->version )) return 0; pdu = snmp_pdu_create(AGENTX_MSG_REGISTER); if ( pdu == NULL ) return 0; pdu->time = 0; pdu->priority = priority; pdu->sessid = ss->sessid; pdu->range_subid = range_subid; if ( range_subid ) { snmp_pdu_add_variable( pdu, start, startlen, ASN_OBJECT_ID, (u_char *)start, startlen); pdu->variables->val.objid[ range_subid-1 ] = range_ubound; } else snmp_add_null_var( pdu, start, startlen); if ( agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS ) { DEBUGMSGTL(("agentx/subagent","registering failed!\n")); return 0; } if ( response->errstat != SNMP_ERR_NOERROR ) { DEBUGMSGTL(("agentx/subagent","registering pdu failed: %d!\n", response->errstat)); snmp_free_pdu(response); return 0; } snmp_free_pdu(response); DEBUGMSGTL(("agentx/subagent","registered\n")); return 1; }
/* * * AgentX State diagram. [mode] = internal mode it's mapped from: * * TESTSET -success-> COMMIT -success-> CLEANUP * [RESERVE1] [ACTION] [COMMIT] * | | * | \--failure-> UNDO * | [UNDO] * | * --failure-> CLEANUP * [FREE] */ int agentx_master_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_session *ax_session = (netsnmp_session *) handler->myvoid; netsnmp_request_info *request = requests; netsnmp_pdu *pdu; void *cb_data; int result; DEBUGMSGTL(("agentx/master", "agentx master handler starting, mode = 0x%02x\n", reqinfo->mode)); if (!ax_session) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR); return SNMP_ERR_NOERROR; } /* * build a new pdu based on the pdu type coming in */ switch (reqinfo->mode) { case MODE_GET: pdu = snmp_pdu_create(AGENTX_MSG_GET); break; case MODE_GETNEXT: pdu = snmp_pdu_create(AGENTX_MSG_GETNEXT); break; case MODE_GETBULK: /* WWWXXX */ pdu = snmp_pdu_create(AGENTX_MSG_GETNEXT); break; case MODE_SET_RESERVE1: pdu = snmp_pdu_create(AGENTX_MSG_TESTSET); break; case MODE_SET_RESERVE2: /* * don't do anything here for AgentX. Assume all is fine * and go on since AgentX only has one test phase. */ return SNMP_ERR_NOERROR; case MODE_SET_ACTION: pdu = snmp_pdu_create(AGENTX_MSG_COMMITSET); break; case MODE_SET_UNDO: pdu = snmp_pdu_create(AGENTX_MSG_UNDOSET); break; case MODE_SET_COMMIT: case MODE_SET_FREE: pdu = snmp_pdu_create(AGENTX_MSG_CLEANUPSET); break; default: snmp_log(LOG_WARNING, "unsupported mode for agentx/master called\n"); return SNMP_ERR_NOERROR; } if (!pdu) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR); return SNMP_ERR_NOERROR; } pdu->version = AGENTX_VERSION_1; pdu->reqid = snmp_get_next_transid(); pdu->transid = reqinfo->asp->pdu->transid; pdu->sessid = ax_session->subsession->sessid; if (reginfo->contextName) { pdu->community = (u_char *) strdup(reginfo->contextName); pdu->community_len = strlen(reginfo->contextName); pdu->flags |= AGENTX_MSG_FLAG_NON_DEFAULT_CONTEXT; } if (ax_session->subsession->flags & AGENTX_MSG_FLAG_NETWORK_BYTE_ORDER) pdu->flags |= AGENTX_MSG_FLAG_NETWORK_BYTE_ORDER; while (request) { size_t nlen = request->requestvb->name_length; oid *nptr = request->requestvb->name; DEBUGMSGTL(("agentx/master","request for variable (")); DEBUGMSGOID(("agentx/master", nptr, nlen)); DEBUGMSG(("agentx/master", ")\n")); /* * loop through all the requests and create agentx ones out of them */ if (reqinfo->mode == MODE_GETNEXT || reqinfo->mode == MODE_GETBULK) { if (snmp_oid_compare(nptr, nlen, request->subtree->start_a, request->subtree->start_len) < 0) { DEBUGMSGTL(("agentx/master","inexact request preceeding region (")); DEBUGMSGOID(("agentx/master", request->subtree->start_a, request->subtree->start_len)); DEBUGMSG(("agentx/master", ")\n")); nptr = request->subtree->start_a; nlen = request->subtree->start_len; request->inclusive = 1; } if (request->inclusive) { DEBUGMSGTL(("agentx/master", "INCLUSIVE varbind ")); DEBUGMSGOID(("agentx/master", nptr, nlen)); DEBUGMSG(("agentx/master", " scoped to ")); DEBUGMSGOID(("agentx/master", request->range_end, request->range_end_len)); DEBUGMSG(("agentx/master", "\n")); snmp_pdu_add_variable(pdu, nptr, nlen, ASN_PRIV_INCL_RANGE, (u_char *) request->range_end, request->range_end_len * sizeof(oid)); request->inclusive = 0; } else { DEBUGMSGTL(("agentx/master", "EXCLUSIVE varbind ")); DEBUGMSGOID(("agentx/master", nptr, nlen)); DEBUGMSG(("agentx/master", " scoped to ")); DEBUGMSGOID(("agentx/master", request->range_end, request->range_end_len)); DEBUGMSG(("agentx/master", "\n")); snmp_pdu_add_variable(pdu, nptr, nlen, ASN_PRIV_EXCL_RANGE, (u_char *) request->range_end, request->range_end_len * sizeof(oid)); } } else { snmp_pdu_add_variable(pdu, request->requestvb->name, request->requestvb->name_length, request->requestvb->type, request->requestvb->val.string, request->requestvb->val_len); } /* * mark the request as delayed */ if (pdu->command != AGENTX_MSG_CLEANUPSET) request->delegated = REQUEST_IS_DELEGATED; else request->delegated = REQUEST_IS_NOT_DELEGATED; /* * next... */ request = request->next; } /* * When the master sends a CleanupSet PDU, it will never get a response * back from the subagent. So we shouldn't allocate the * netsnmp_delegated_cache structure in this case. */ if (pdu->command != AGENTX_MSG_CLEANUPSET) cb_data = netsnmp_create_delegated_cache(handler, reginfo, reqinfo, requests, (void *) ax_session); else cb_data = NULL; /* * send the requests out. */ DEBUGMSGTL(("agentx", "sending pdu (req=0x%x,trans=0x%x,sess=0x%x)\n", (unsigned)pdu->reqid, (unsigned)pdu->transid, (unsigned)pdu->sessid)); result = snmp_async_send(ax_session, pdu, agentx_got_response, cb_data); if (result == 0) { snmp_free_pdu(pdu); } return SNMP_ERR_NOERROR; }
/* * Configure special parameters on the session. * Currently takes the parameter configured and changes it if something * was configured. It becomes "-c" if the community string from the pdu * is placed on the session. */ int proxy_fill_in_session(netsnmp_mib_handler *handler, netsnmp_agent_request_info *reqinfo, void **configured) { netsnmp_session *session; struct simple_proxy *sp; sp = (struct simple_proxy *) handler->myvoid; if (!sp) { return 0; } session = sp->sess; if (!session) { return 0; } #if !defined(DISABLE_SNMPV1) || !defined(DISABLE_SNMPV2C) #if defined(DISABLE_SNMPV1) if (session->version == SNMP_VERSION_2c) { #else #if defined(DISABLE_SNMPV2C) if (session->version == SNMP_VERSION_1) { #else if (session->version == SNMP_VERSION_1 || session->version == SNMP_VERSION_2c) { #endif #endif /* * Check if session has community string defined for it. * If not, need to extract community string from the pdu. * Copy to session and set 'configured' to indicate this. */ if (session->community_len == 0) { DEBUGMSGTL(("proxy", "session has no community string\n")); if (reqinfo->asp == NULL || reqinfo->asp->pdu == NULL || reqinfo->asp->pdu->community_len == 0) { return 0; } *configured = malloc(strlen("-c") + 1); strcpy(*configured, "-c"); DEBUGMSGTL(("proxy", "pdu has community string\n")); session->community_len = reqinfo->asp->pdu->community_len; session->community = malloc(session->community_len + 1); strncpy((char *)session->community, (const char *)reqinfo->asp->pdu->community, session->community_len); } } #endif return 1; } /* * Free any specially configured parameters used on the session. */ void proxy_free_filled_in_session_args(netsnmp_session *session, void **configured) { /* Only do comparisions, etc., if something was configured */ if (*configured == NULL) { return; } /* If used community string from pdu, release it from session now */ if (strcmp((const char *)(*configured), "-c") == 0) { free(session->community); session->community = NULL; session->community_len = 0; } free((u_char *)(*configured)); *configured = NULL; } void init_proxy(void) { snmpd_register_config_handler("proxy", proxy_parse_config, proxy_free_config, "[snmpcmd args] host oid [remoteoid]"); } void shutdown_proxy(void) { proxy_free_config(); } int proxy_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_pdu *pdu; struct simple_proxy *sp; oid *ourname; size_t ourlength; netsnmp_request_info *request = requests; u_char *configured = NULL; DEBUGMSGTL(("proxy", "proxy handler starting, mode = %d\n", reqinfo->mode)); switch (reqinfo->mode) { case MODE_GET: case MODE_GETNEXT: case MODE_GETBULK: /* WWWXXX */ pdu = snmp_pdu_create(reqinfo->mode); break; case MODE_SET_ACTION: pdu = snmp_pdu_create(SNMP_MSG_SET); break; case MODE_SET_UNDO: /* * If we set successfully (status == NOERROR), * we can't back out again, so need to report the fact. * If we failed to set successfully, then we're fine. */ for (request = requests; request; request=request->next) { if (request->status == SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_UNDOFAILED); return SNMP_ERR_UNDOFAILED; } } return SNMP_ERR_NOERROR; case MODE_SET_RESERVE1: case MODE_SET_RESERVE2: case MODE_SET_FREE: case MODE_SET_COMMIT: /* * Nothing to do in this pass */ return SNMP_ERR_NOERROR; default: snmp_log(LOG_WARNING, "unsupported mode for proxy called (%d)\n", reqinfo->mode); return SNMP_ERR_NOERROR; } sp = (struct simple_proxy *) handler->myvoid; if (!pdu || !sp) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR); return SNMP_ERR_NOERROR; } while (request) { ourname = request->requestvb->name; ourlength = request->requestvb->name_length; if (sp->base_len > 0) { if ((ourlength - sp->name_len + sp->base_len) > MAX_OID_LEN) { /* * too large */ snmp_log(LOG_ERR, "proxy oid request length is too long\n"); return SNMP_ERR_NOERROR; } /* * suffix appended? */ DEBUGMSGTL(("proxy", "length=%d, base_len=%d, name_len=%d\n", ourlength, sp->base_len, sp->name_len)); if (ourlength > (int) sp->name_len) memcpy(&(sp->base[sp->base_len]), &(ourname[sp->name_len]), sizeof(oid) * (ourlength - sp->name_len)); ourlength = ourlength - sp->name_len + sp->base_len; ourname = sp->base; } snmp_pdu_add_variable(pdu, ourname, ourlength, request->requestvb->type, request->requestvb->val.string, request->requestvb->val_len); request->delegated = 1; request = request->next; } /* * Customize session parameters based on request information */ if (!proxy_fill_in_session(handler, reqinfo, (void **)&configured)) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR); return SNMP_ERR_NOERROR; } /* * send the request out */ DEBUGMSGTL(("proxy", "sending pdu\n")); snmp_async_send(sp->sess, pdu, proxy_got_response, netsnmp_create_delegated_cache(handler, reginfo, reqinfo, requests, (void *) sp)); /* Free any special parameters generated on the session */ proxy_free_filled_in_session_args(sp->sess, (void **)&configured); return SNMP_ERR_NOERROR; }
int main(int argc, char *argv[]) { netsnmp_session session, *ss; netsnmp_pdu *pdu = NULL, *response = NULL; int arg; size_t name_length = USM_OID_LEN; size_t name_length2 = USM_OID_LEN; int status; int exitval = 1; int rval; int command = 0; long longvar; size_t oldKu_len = SNMP_MAXBUF_SMALL, newKu_len = SNMP_MAXBUF_SMALL, oldkul_len = SNMP_MAXBUF_SMALL, oldkulpriv_len = SNMP_MAXBUF_SMALL, newkulpriv_len = SNMP_MAXBUF_SMALL, newkul_len = SNMP_MAXBUF_SMALL, keychange_len = SNMP_MAXBUF_SMALL, keychangepriv_len = SNMP_MAXBUF_SMALL; char *newpass = NULL, *oldpass = NULL; u_char oldKu[SNMP_MAXBUF_SMALL], newKu[SNMP_MAXBUF_SMALL], oldkul[SNMP_MAXBUF_SMALL], oldkulpriv[SNMP_MAXBUF_SMALL], newkulpriv[SNMP_MAXBUF_SMALL], newkul[SNMP_MAXBUF_SMALL], keychange[SNMP_MAXBUF_SMALL], keychangepriv[SNMP_MAXBUF_SMALL]; SOCK_STARTUP; authKeyChange = authKeyOid; privKeyChange = privKeyOid; /* * get the common command line arguments */ switch (arg = snmp_parse_args(argc, argv, &session, "C:", optProc)) { case NETSNMP_PARSE_ARGS_ERROR: goto out; case NETSNMP_PARSE_ARGS_SUCCESS_EXIT: exitval = 0; goto out; case NETSNMP_PARSE_ARGS_ERROR_USAGE: usage(); goto out; default: break; } if (arg >= argc) { fprintf(stderr, "Please specify an operation to perform.\n"); usage(); goto out; } /* * open an SNMP session */ /* * Note: this needs to obtain the engineID used below */ session.flags &= ~SNMP_FLAGS_DONT_PROBE; ss = snmp_open(&session); if (ss == NULL) { /* * diagnose snmp_open errors with the input netsnmp_session pointer */ snmp_sess_perror("snmpusm", &session); goto out; } /* * set usmUserEngineID from ss->contextEngineID * if not already set (via -CE) */ if (usmUserEngineID == NULL) { usmUserEngineID = ss->contextEngineID; usmUserEngineIDLen = ss->contextEngineIDLen; } /* * create PDU for SET request and add object names and values to request */ pdu = snmp_pdu_create(SNMP_MSG_SET); if (!pdu) { fprintf(stderr, "Failed to create request\n"); goto close_session; } if (strcmp(argv[arg], CMD_PASSWD_NAME) == 0) { /* * passwd: change a users password. * * XXX: Uses the auth type of the calling user, a MD5 user can't * change a SHA user's key. */ char *passwd_user; command = CMD_PASSWD; oldpass = argv[++arg]; newpass = argv[++arg]; passwd_user = argv[++arg]; if (doprivkey == 0 && doauthkey == 0) doprivkey = doauthkey = 1; if (newpass == NULL || strlen(newpass) < USM_LENGTH_P_MIN) { fprintf(stderr, "New passphrase must be greater than %d characters in length.\n", USM_LENGTH_P_MIN); goto close_session; } if (oldpass == NULL || strlen(oldpass) < USM_LENGTH_P_MIN) { fprintf(stderr, "Old passphrase must be greater than %d characters in length.\n", USM_LENGTH_P_MIN); goto close_session; } DEBUGMSGTL(("9:usm:passwd", "oldpass len %" NETSNMP_PRIz "d, newpass len %" NETSNMP_PRIz "d\n", strlen(oldpass), strlen(newpass))); /* * Change the user supplied on command line. */ if ((passwd_user != NULL) && (strlen(passwd_user) > 0)) { session.securityName = passwd_user; } else { /* * Use own key object if no user was supplied. */ authKeyChange = ownAuthKeyOid; privKeyChange = ownPrivKeyOid; } /* * do we have a securityName? If not, copy the default */ if (session.securityName == NULL) { session.securityName = strdup(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_SECNAME)); } /* * the old Ku is in the session, but we need the new one */ if (session.securityAuthProto == NULL) { /* * get .conf set default */ const oid *def = get_default_authtype(&session.securityAuthProtoLen); session.securityAuthProto = snmp_duplicate_objid(def, session.securityAuthProtoLen); } if (session.securityAuthProto == NULL) { /* * assume MD5 */ #ifndef NETSNMP_DISABLE_MD5 session.securityAuthProtoLen = sizeof(usmHMACMD5AuthProtocol) / sizeof(oid); session.securityAuthProto = snmp_duplicate_objid(usmHMACMD5AuthProtocol, session.securityAuthProtoLen); #else session.securityAuthProtoLen = sizeof(usmHMACSHA1AuthProtocol) / sizeof(oid); session.securityAuthProto = snmp_duplicate_objid(usmHMACSHA1AuthProtocol, session.securityAuthProtoLen); #endif } if (uselocalizedkey && (strncmp(oldpass, "0x", 2) == 0)) { /* * use the localized key from the command line */ u_char *buf; size_t buf_len = SNMP_MAXBUF_SMALL; buf = (u_char *) malloc (buf_len * sizeof(u_char)); oldkul_len = 0; /* initialize the offset */ if (!snmp_hex_to_binary((u_char **) (&buf), &buf_len, &oldkul_len, 0, oldpass)) { snmp_perror(argv[0]); fprintf(stderr, "generating the old Kul from localized key failed\n"); goto close_session; } memcpy(oldkul, buf, oldkul_len); SNMP_FREE(buf); } else { /* * the old Ku is in the session, but we need the new one */ rval = generate_Ku(session.securityAuthProto, session.securityAuthProtoLen, (u_char *) oldpass, strlen(oldpass), oldKu, &oldKu_len); if (rval != SNMPERR_SUCCESS) { snmp_perror(argv[0]); fprintf(stderr, "generating the old Ku failed\n"); goto close_session; } /* * generate the two Kul's */ rval = generate_kul(session.securityAuthProto, session.securityAuthProtoLen, usmUserEngineID, usmUserEngineIDLen, oldKu, oldKu_len, oldkul, &oldkul_len); if (rval != SNMPERR_SUCCESS) { snmp_perror(argv[0]); fprintf(stderr, "generating the old Kul failed\n"); goto close_session; } DEBUGMSGTL(("9:usm:passwd", "oldkul len %" NETSNMP_PRIz "d\n", oldkul_len)); } if (uselocalizedkey && (strncmp(newpass, "0x", 2) == 0)) { /* * use the localized key from the command line */ u_char *buf; size_t buf_len = SNMP_MAXBUF_SMALL; buf = (u_char *) malloc (buf_len * sizeof(u_char)); newkul_len = 0; /* initialize the offset */ if (!snmp_hex_to_binary((u_char **) (&buf), &buf_len, &newkul_len, 0, newpass)) { snmp_perror(argv[0]); fprintf(stderr, "generating the new Kul from localized key failed\n"); goto close_session; } memcpy(newkul, buf, newkul_len); SNMP_FREE(buf); } else { rval = generate_Ku(session.securityAuthProto, session.securityAuthProtoLen, (u_char *) newpass, strlen(newpass), newKu, &newKu_len); if (rval != SNMPERR_SUCCESS) { snmp_perror(argv[0]); fprintf(stderr, "generating the new Ku failed\n"); goto close_session; } rval = generate_kul(session.securityAuthProto, session.securityAuthProtoLen, usmUserEngineID, usmUserEngineIDLen, newKu, newKu_len, newkul, &newkul_len); if (rval != SNMPERR_SUCCESS) { snmp_perror(argv[0]); fprintf(stderr, "generating the new Kul failed\n"); goto close_session; } DEBUGMSGTL(("9:usm:passwd", "newkul len %" NETSNMP_PRIz "d\n", newkul_len)); } /* * for encryption, we may need to truncate the key to the proper length * so we need two copies. For simplicity, we always just copy even if * they're the same lengths. */ if (doprivkey) { int privtype, properlength; u_char *okp = oldkulpriv, *nkp = newkulpriv; if (!session.securityPrivProto) { snmp_log(LOG_ERR, "no encryption type specified, which I need in order to know to change the key\n"); goto close_session; } privtype = sc_get_privtype(session.securityPrivProto, session.securityPrivProtoLen); properlength = sc_get_proper_priv_length_bytype(privtype); if (USM_CREATE_USER_PRIV_DES == privtype) properlength *= 2; /* ?? we store salt with key */ DEBUGMSGTL(("9:usm:passwd", "proper len %d\n", properlength)); oldkulpriv_len = oldkul_len; newkulpriv_len = newkul_len; memcpy(oldkulpriv, oldkul, oldkulpriv_len); memcpy(newkulpriv, newkul, newkulpriv_len); if (oldkulpriv_len > properlength) { oldkulpriv_len = newkulpriv_len = properlength; } else if (oldkulpriv_len < properlength) { rval = netsnmp_extend_kul(properlength, session.securityAuthProto, session.securityAuthProtoLen, privtype, usmUserEngineID, usmUserEngineIDLen, &okp, &oldkulpriv_len, sizeof(oldkulpriv)); rval = netsnmp_extend_kul(properlength, session.securityAuthProto, session.securityAuthProtoLen, privtype, usmUserEngineID, usmUserEngineIDLen, &nkp, &newkulpriv_len, sizeof(newkulpriv)); } } /* * create the keychange string */ if (doauthkey) { rval = encode_keychange(session.securityAuthProto, session.securityAuthProtoLen, oldkul, oldkul_len, newkul, newkul_len, keychange, &keychange_len); if (rval != SNMPERR_SUCCESS) { snmp_perror(argv[0]); fprintf(stderr, "encoding the keychange failed\n"); usage(); goto close_session; } } /* which is slightly different for encryption if lengths are different */ if (doprivkey) { DEBUGMSGTL(("9:usm:passwd:encode", "proper len %" NETSNMP_PRIz "d, old_len %" NETSNMP_PRIz "d, new_len %" NETSNMP_PRIz "d\n", oldkulpriv_len, oldkulpriv_len, newkulpriv_len)); rval = encode_keychange(session.securityAuthProto, session.securityAuthProtoLen, oldkulpriv, oldkulpriv_len, newkulpriv, newkulpriv_len, keychangepriv, &keychangepriv_len); DEBUGMSGTL(("9:usm:passwd:encode", "keychange len %" NETSNMP_PRIz "d\n", keychangepriv_len)); if (rval != SNMPERR_SUCCESS) { snmp_perror(argv[0]); fprintf(stderr, "encoding the keychange failed\n"); usage(); goto close_session; } } /* * add the keychange string to the outgoing packet */ if (doauthkey) { setup_oid(authKeyChange, &name_length, usmUserEngineID, usmUserEngineIDLen, session.securityName); snmp_pdu_add_variable(pdu, authKeyChange, name_length, ASN_OCTET_STR, keychange, keychange_len); } if (doprivkey) { setup_oid(privKeyChange, &name_length2, usmUserEngineID, usmUserEngineIDLen, session.securityName); snmp_pdu_add_variable(pdu, privKeyChange, name_length2, ASN_OCTET_STR, keychangepriv, keychangepriv_len); } } else if (strcmp(argv[arg], CMD_CREATE_NAME) == 0) { /* * create: create a user * * create USER [CLONEFROM] */ if (++arg >= argc) { fprintf(stderr, "You must specify the user name to create\n"); usage(); goto close_session; } command = CMD_CREATE; if (++arg < argc) { /* * clone the new user from an existing user * (and make them active immediately) */ setup_oid(usmUserStatus, &name_length, usmUserEngineID, usmUserEngineIDLen, argv[arg-1]); if (docreateandwait) { longvar = RS_CREATEANDWAIT; } else { longvar = RS_CREATEANDGO; } snmp_pdu_add_variable(pdu, usmUserStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof(longvar)); name_length = USM_OID_LEN; setup_oid(usmUserCloneFrom, &name_length, usmUserEngineID, usmUserEngineIDLen, argv[arg - 1]); setup_oid(usmUserSecurityName, &name_length2, usmUserEngineID, usmUserEngineIDLen, argv[arg]); snmp_pdu_add_variable(pdu, usmUserCloneFrom, name_length, ASN_OBJECT_ID, (u_char *) usmUserSecurityName, sizeof(oid) * name_length2); } else { /* * create a new (unauthenticated) user from scratch * The Net-SNMP agent won't allow such a user to be made active. */ setup_oid(usmUserStatus, &name_length, usmUserEngineID, usmUserEngineIDLen, argv[arg-1]); longvar = RS_CREATEANDWAIT; snmp_pdu_add_variable(pdu, usmUserStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof(longvar)); } } else if (strcmp(argv[arg], CMD_CLONEFROM_NAME) == 0) { /* * create: clone a user from another * * cloneFrom USER FROM */ if (++arg >= argc) { fprintf(stderr, "You must specify the user name to operate on\n"); usage(); goto close_session; } command = CMD_CLONEFROM; setup_oid(usmUserStatus, &name_length, usmUserEngineID, usmUserEngineIDLen, argv[arg]); longvar = RS_ACTIVE; snmp_pdu_add_variable(pdu, usmUserStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof(longvar)); name_length = USM_OID_LEN; setup_oid(usmUserCloneFrom, &name_length, usmUserEngineID, usmUserEngineIDLen, argv[arg]); if (++arg >= argc) { fprintf(stderr, "You must specify the user name to clone from\n"); usage(); goto close_session; } setup_oid(usmUserSecurityName, &name_length2, usmUserEngineID, usmUserEngineIDLen, argv[arg]); snmp_pdu_add_variable(pdu, usmUserCloneFrom, name_length, ASN_OBJECT_ID, (u_char *) usmUserSecurityName, sizeof(oid) * name_length2); } else if (strcmp(argv[arg], CMD_DELETE_NAME) == 0) { /* * delete: delete a user * * delete USER */ if (++arg >= argc) { fprintf(stderr, "You must specify the user name to delete\n"); goto close_session; } command = CMD_DELETE; setup_oid(usmUserStatus, &name_length, usmUserEngineID, usmUserEngineIDLen, argv[arg]); longvar = RS_DESTROY; snmp_pdu_add_variable(pdu, usmUserStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof(longvar)); } else if (strcmp(argv[arg], CMD_ACTIVATE_NAME) == 0) { /* * activate: activate a user * * activate USER */ if (++arg >= argc) { fprintf(stderr, "You must specify the user name to activate\n"); goto close_session; } command = CMD_ACTIVATE; setup_oid(usmUserStatus, &name_length, usmUserEngineID, usmUserEngineIDLen, argv[arg]); longvar = RS_ACTIVE; snmp_pdu_add_variable(pdu, usmUserStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof(longvar)); } else if (strcmp(argv[arg], CMD_DEACTIVATE_NAME) == 0) { /* * deactivate: deactivate a user * * deactivate USER */ if (++arg >= argc) { fprintf(stderr, "You must specify the user name to deactivate\n"); goto close_session; } command = CMD_DEACTIVATE; setup_oid(usmUserStatus, &name_length, usmUserEngineID, usmUserEngineIDLen, argv[arg]); longvar = RS_NOTINSERVICE; snmp_pdu_add_variable(pdu, usmUserStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof(longvar)); #if defined(HAVE_OPENSSL_DH_H) && defined(HAVE_LIBCRYPTO) } else if (strcmp(argv[arg], CMD_CHANGEKEY_NAME) == 0) { /* * change the key of a user if DH is available */ char *passwd_user; netsnmp_pdu *dhpdu, *dhresponse = NULL; netsnmp_variable_list *vars, *dhvar; command = CMD_CHANGEKEY; name_length = DH_USM_OID_LEN; name_length2 = DH_USM_OID_LEN; passwd_user = argv[++arg]; if (doprivkey == 0 && doauthkey == 0) doprivkey = doauthkey = 1; /* * Change the user supplied on command line. */ if ((passwd_user != NULL) && (strlen(passwd_user) > 0)) { session.securityName = passwd_user; } else { /* * Use own key object if no user was supplied. */ dhauthKeyChange = usmDHUserOwnAuthKeyChange; dhprivKeyChange = usmDHUserOwnPrivKeyChange; } /* * do we have a securityName? If not, copy the default */ if (session.securityName == NULL) { session.securityName = strdup(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_SECNAME)); } /* fetch the needed diffie helman parameters */ dhpdu = snmp_pdu_create(SNMP_MSG_GET); if (!dhpdu) { fprintf(stderr, "Failed to create DH request\n"); goto close_session; } /* get the current DH parameters */ snmp_add_null_var(dhpdu, usmDHParameters, usmDHParameters_len); /* maybe the auth key public value */ if (doauthkey) { setup_oid(dhauthKeyChange, &name_length, usmUserEngineID, usmUserEngineIDLen, session.securityName); snmp_add_null_var(dhpdu, dhauthKeyChange, name_length); } /* maybe the priv key public value */ if (doprivkey) { setup_oid(dhprivKeyChange, &name_length2, usmUserEngineID, usmUserEngineIDLen, session.securityName); snmp_add_null_var(dhpdu, dhprivKeyChange, name_length2); } /* fetch the values */ status = snmp_synch_response(ss, dhpdu, &dhresponse); if (status != SNMPERR_SUCCESS || dhresponse == NULL || dhresponse->errstat != SNMP_ERR_NOERROR || dhresponse->variables->type != ASN_OCTET_STR) { snmp_sess_perror("snmpusm", ss); if (dhresponse && dhresponse->variables && dhresponse->variables->type != ASN_OCTET_STR) { fprintf(stderr, "Can't get diffie-helman exchange from the agent\n"); fprintf(stderr, " (maybe it doesn't support the SNMP-USM-DH-OBJECTS-MIB MIB)\n"); } exitval = 1; goto begone; } dhvar = dhresponse->variables; vars = dhvar->next_variable; /* complete the DH equation & print resulting keys */ if (doauthkey) { if (get_USM_DH_key(vars, dhvar, sc_get_properlength(ss->securityAuthProto, ss->securityAuthProtoLen), pdu, "auth", dhauthKeyChange, name_length) != SNMPERR_SUCCESS) goto begone; vars = vars->next_variable; } if (doprivkey) { size_t dhprivKeyLen = 0; int privtype = sc_get_privtype(ss->securityPrivProto, ss->securityPrivProtoLen); dhprivKeyLen = sc_get_proper_priv_length_bytype(privtype); if (USM_CREATE_USER_PRIV_DES == privtype) dhprivKeyLen *= 2; /* ?? we store salt with key */ if (get_USM_DH_key(vars, dhvar, dhprivKeyLen, pdu, "priv", dhprivKeyChange, name_length2) != SNMPERR_SUCCESS) goto begone; vars = vars->next_variable; } /* snmp_free_pdu(dhresponse); */ /* parts still in use somewhere */ #endif /* HAVE_OPENSSL_DH_H && HAVE_LIBCRYPTO */ } else { fprintf(stderr, "Unknown command\n"); usage(); goto close_session; } /* * add usmUserPublic if specified (via -Cp) */ if (usmUserPublic_val) { name_length = USM_OID_LEN; setup_oid(usmUserPublic, &name_length, usmUserEngineID, usmUserEngineIDLen, session.securityName); snmp_pdu_add_variable(pdu, usmUserPublic, name_length, ASN_OCTET_STR, usmUserPublic_val, strlen(usmUserPublic_val)); } /* * do the request */ status = snmp_synch_response(ss, pdu, &response); if (status == STAT_SUCCESS) { if (response) { if (response->errstat == SNMP_ERR_NOERROR) { fprintf(stdout, "%s\n", successNotes[command - 1]); } else { fprintf(stderr, "Error in packet.\nReason: %s\n", snmp_errstring(response->errstat)); if (response->errindex != 0) { int count; netsnmp_variable_list *vars; fprintf(stderr, "Failed object: "); for (count = 1, vars = response->variables; vars && count != response->errindex; vars = vars->next_variable, count++) /*EMPTY*/; if (vars) fprint_objid(stderr, vars->name, vars->name_length); fprintf(stderr, "\n"); } exitval = 2; } } } else if (status == STAT_TIMEOUT) { fprintf(stderr, "Timeout: No Response from %s\n", session.peername); exitval = 1; } else { /* status == STAT_ERROR */ snmp_sess_perror("snmpset", ss); exitval = 1; } exitval = 0; #if defined(HAVE_OPENSSL_DH_H) && defined(HAVE_LIBCRYPTO) begone: #endif /* HAVE_OPENSSL_DH_H && HAVE_LIBCRYPTO */ if (response) snmp_free_pdu(response); close_session: snmp_close(ss); out: SOCK_CLEANUP; return exitval; }
int get_USM_DH_key(netsnmp_variable_list *vars, netsnmp_variable_list *dhvar, size_t outkey_len, netsnmp_pdu *pdu, const char *keyname, oid *keyoid, size_t keyoid_len) { u_char *dhkeychange; DH *dh; const BIGNUM *p, *g, *pub_key; BIGNUM *other_pub; u_char *key; size_t key_len; dhkeychange = (u_char *) malloc(2 * vars->val_len * sizeof(char)); if (!dhkeychange) return SNMPERR_GENERR; memcpy(dhkeychange, vars->val.string, vars->val_len); { const unsigned char *cp = dhvar->val.string; dh = d2i_DHparams(NULL, &cp, dhvar->val_len); } if (dh) DH_get0_pqg(dh, &p, NULL, &g); if (!dh || !g || !p) { SNMP_FREE(dhkeychange); return SNMPERR_GENERR; } if (!DH_generate_key(dh)) { SNMP_FREE(dhkeychange); return SNMPERR_GENERR; } DH_get0_key(dh, &pub_key, NULL); if (vars->val_len != (unsigned int)BN_num_bytes(pub_key)) { SNMP_FREE(dhkeychange); fprintf(stderr,"incorrect diffie-helman lengths (%lu != %d)\n", (unsigned long)vars->val_len, BN_num_bytes(pub_key)); return SNMPERR_GENERR; } BN_bn2bin(pub_key, dhkeychange + vars->val_len); key_len = DH_size(dh); if (!key_len) { SNMP_FREE(dhkeychange); return SNMPERR_GENERR; } key = (u_char *) malloc(key_len * sizeof(u_char)); if (!key) { SNMP_FREE(dhkeychange); return SNMPERR_GENERR; } other_pub = BN_bin2bn(vars->val.string, vars->val_len, NULL); if (!other_pub) { SNMP_FREE(dhkeychange); SNMP_FREE(key); return SNMPERR_GENERR; } if (DH_compute_key(key, other_pub, dh)) { u_char *kp; printf("new %s key: 0x", keyname); for(kp = key + key_len - outkey_len; kp - key < (int)key_len; kp++) { printf("%02x", (unsigned char) *kp); } printf("\n"); } snmp_pdu_add_variable(pdu, keyoid, keyoid_len, ASN_OCTET_STR, dhkeychange, 2 * vars->val_len); SNMP_FREE(dhkeychange); SNMP_FREE(other_pub); SNMP_FREE(key); return SNMPERR_SUCCESS; }
int proxy_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_pdu *pdu; struct simple_proxy *sp; oid *ourname; size_t ourlength; netsnmp_request_info *request = requests; DEBUGMSGTL(("proxy", "proxy handler starting, mode = %d\n", reqinfo->mode)); switch (reqinfo->mode) { case MODE_GET: case MODE_GETNEXT: case MODE_GETBULK: /* WWWXXX */ pdu = snmp_pdu_create(reqinfo->mode); break; case MODE_SET_COMMIT: pdu = snmp_pdu_create(SNMP_MSG_SET); break; default: snmp_log(LOG_WARNING, "unsupported mode for proxy called\n"); return SNMP_ERR_NOERROR; } sp = (struct simple_proxy *) handler->myvoid; if (!pdu || !sp) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR); return SNMP_ERR_NOERROR; } while (request) { ourname = request->requestvb->name; ourlength = request->requestvb->name_length; if (sp->base_len > 0) { if ((ourlength - sp->name_len + sp->base_len) > MAX_OID_LEN) { /* * too large */ snmp_log(LOG_ERR, "proxy oid request length is too long\n"); return SNMP_ERR_NOERROR; } /* * suffix appended? */ DEBUGMSGTL(("proxy", "length=%d, base_len=%d, name_len=%d\n", ourlength, sp->base_len, sp->name_len)); if (ourlength > (int) sp->name_len) memcpy(&(sp->base[sp->base_len]), &(ourname[sp->name_len]), sizeof(oid) * (ourlength - sp->name_len)); ourlength = ourlength - sp->name_len + sp->base_len; ourname = sp->base; } snmp_pdu_add_variable(pdu, ourname, ourlength, request->requestvb->type, request->requestvb->val.string, request->requestvb->val_len); request->delegated = 1; request = request->next; } /* * send the request out */ DEBUGMSGTL(("proxy", "sending pdu\n")); snmp_async_send(sp->sess, pdu, proxy_got_response, netsnmp_create_delegated_cache(handler, reginfo, reqinfo, requests, (void *) sp)); return SNMP_ERR_NOERROR; }
/** * snmp_set * @ss: a handle to the snmp session needed to make an snmp transaction. * @objid: string containing the OID to set. * @value: the value to set the oid with. * * Sets a value where indicated by the objectid * using snmp. * * Returns: 0 if Success, less than 0 if Failure. **/ SaErrorT snmp_set( struct snmp_session *ss, char *objid, struct snmp_value value) { struct snmp_pdu *pdu; struct snmp_pdu *response; oid anOID[MAX_OID_LEN]; size_t anOID_len = MAX_OID_LEN; void *dataptr = NULL; int status = 0; SaErrorT rtncode = 0; /* * Create the PDU for the data for our request. */ pdu = snmp_pdu_create(SNMP_MSG_SET); read_objid(objid, anOID, &anOID_len); rtncode = 0; /* Default - All is OK */ switch (value.type) { case ASN_INTEGER: case ASN_UNSIGNED: case ASN_COUNTER: dataptr = &value.integer; break; case ASN_OCTET_STR: dataptr = value.string; break; default: rtncode = SA_ERR_HPI_INVALID_PARAMS; dbg("datatype %c not yet supported by snmp_set()\n", value.type); break; } if (rtncode == 0) { /* * Set the data to send out */ /* Old code - int rc = snmp_add_var(pdu, objid, objid_len, datatype, dataptr) */ /* was missing checking for rc, so there was no OID and no data was */ /* included in the package. */ /* Since snmp_add_var() converts input data to string then call */ /* snmp_pdu_add_variable(), we stick with add_variable() for efficiency */ snmp_pdu_add_variable(pdu, anOID, anOID_len, value.type, dataptr, value.str_len); /* * Send the Request out. */ status = snmp_synch_response(ss, pdu, &response); /* * Process the response. */ if (status == STAT_SUCCESS) rtncode = errstat2hpi(response->errstat); else { snmp_sess_perror("snmpset", ss); rtncode = snmpstat2hpi(status);; } /* Clean up: free the response */ if (response) snmp_free_pdu(response); } return rtncode; }
/* * Add a null variable with the requested name to the end of the list of * variables for this pdu. */ netsnmp_variable_list * snmp_add_null_var(netsnmp_pdu *pdu, const oid * name, size_t name_length) { return snmp_pdu_add_variable(pdu, name, name_length, ASN_NULL, NULL, 0); }
static int _hook_parse(netsnmp_session * sp, netsnmp_pdu * pdu, u_char * pkt, size_t len) { int i; int rc; u_char *p; oid val; int payload_len; netsnmp_transport *transport; struct asmp_connection *asmp; transport = snmp_sess_transport(snmp_sess_pointer(sp)); if (transport == NULL || transport->data == NULL) return -1; asmp = transport->data; pdu->msgid = pdu->reqid = (pkt[5] << 8) | pkt[6]; pdu->command = pkt[7]; if (pdu->command == 0x90 || pdu->command == 0x91) rc = 1; else rc = SNMP_ERR_NOERROR; p = pkt+12; payload_len = ntohl(*((uint32_t *)(pkt+8))); while (payload_len > 1) { uint16_t vlen; if (*p == ASMP_FIELD_TERM) break; val = *p; vlen = ntohs(*((uint16_t *)(p+1))); if (asmp->proto != ASMP_PROTO_AIDP) { switch (val) { case 1: if (pdu->command >= 0x90 && pdu->command <= 0x92) pdu->errstat = ntohs(*((uint16_t *)(p+3))); break; case 2: if (pdu->command >= 0x90 && pdu->command <= 0x92) pdu->errindex = ntohs(*((uint16_t *)(p+3))); break; case 3: if (pdu->command >= 0x90 && pdu->command <= 0x92) { int nlen; oid *name = NULL; netsnmp_variable_list *var = NULL; p += 3; if (*p != ASN_OBJECT_ID) { fprintf(stderr, "Wrong VarBind data\n"); return rc; } while (vlen > 0) { nlen = (*(p+1) << 8 | *(p+2)); switch (*p) { case ASN_OBJECT_ID: name = calloc(1, nlen); //fprintf(stderr, "OID: "); for (p += 3, i=0; i<nlen/sizeof(oid); i++, p += 4) { name[i] = *p << 24 | *(p+1) << 16 | *(p+2) << 8 | *(p+3); //fprintf(stderr, ".%d", name[i]); } //fprintf(stderr, "\n"); /* move pointer back */ p -= nlen+3; #if 0 if (pkt[16] == 6 && pkt[21] == 1) snmp_pdu_add_variable(pdu, name, nlen, SNMP_ENDOFMIBVIEW, NULL, 0); #endif if (var == NULL) { /* First OID is name OID */ var = snmp_add_null_var(pdu, name, nlen/sizeof(oid)); } else { /* Second OID is value OID */ var->type = *p; snmp_set_var_value(var, (u_char *)name, nlen); } free(name); break; case ASN_COUNTER: case ASN_TIMETICKS: case ASN_GAUGE: case ASN_INTEGER: { int32_t v; v = ntohl(*((int32_t *)(p+3))); var->type = *p; snmp_set_var_value(var, (u_char *)&v, nlen); } break; case ASN_OCTET_STR: var->type = *p; snmp_set_var_value(var, p+3, nlen); break; case ASN_IPADDRESS: var->type = *p; snmp_set_var_value(var, p+3, nlen); break; case ASN_NULL: var->type = *p; snmp_set_var_value(var, NULL, 0); break; default: fprintf(stderr, "AAA: %d\n", *p); break; } p += nlen+3; vlen -= nlen+3; payload_len -= nlen+3; } pdu->command = SNMP_MSG_RESPONSE; rc = SNMP_ERR_NOERROR; } break; default: break; } } else { fprintf(stderr, "Flen: %04x\n", vlen); snmp_pdu_add_variable(pdu, &val, 1, ASN_OCTET_STR, p+3, vlen); } p += vlen+3; payload_len -= vlen+3; } return rc; }
int main (int argc, char *argv[]) { netsnmp_session session, *ss; netsnmp_pdu *pdu = NULL, *response = NULL; #ifdef notused netsnmp_variable_list *vars; #endif int arg; #ifdef notused int count; int current_name = 0; int current_type = 0; int current_value = 0; char *names[128]; char types[128]; char *values[128]; oid name[MAX_OID_LEN]; #endif size_t name_length; int status; int exitval = 0; int command = 0; long longvar; int secModel, secLevel, contextMatch; unsigned int val, i = 0; char *mask, *groupName, *prefix, *authtype; u_char viewMask[VACMSTRINGLEN]; char *st; /* * get the common command line arguments */ switch (arg = snmp_parse_args (argc, argv, &session, "C:", optProc)) { case NETSNMP_PARSE_ARGS_ERROR: exit (1); case NETSNMP_PARSE_ARGS_SUCCESS_EXIT: exit (0); case NETSNMP_PARSE_ARGS_ERROR_USAGE: usage (); exit (1); default: break; } SOCK_STARTUP; /* * open an SNMP session */ /* * Note: this wil obtain the engineID needed below */ ss = snmp_open (&session); if (ss == NULL) { /* * diagnose snmp_open errors with the input netsnmp_session pointer */ snmp_sess_perror ("snmpvacm", &session); exit (1); } /* * create PDU for SET request and add object names and values to request */ pdu = snmp_pdu_create (SNMP_MSG_SET); if (arg >= argc) { fprintf (stderr, "Please specify a operation to perform.\n"); usage (); exit (1); } if (strcmp (argv[arg], CMD_DELETEVIEW_NAME) == 0) /* * deleteView: delete a view * * deleteView NAME SUBTREE * */ { if (++arg + 2 != argc) { fprintf (stderr, "You must specify the view to delete\n"); usage (); exit (1); } command = CMD_DELETEVIEW; name_length = VIEW_OID_LEN; view_oid (vacmViewTreeFamilyStatus, &name_length, argv[arg], argv[arg + 1]); longvar = RS_DESTROY; snmp_pdu_add_variable (pdu, vacmViewTreeFamilyStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof (longvar)); } else if (strcmp (argv[arg], CMD_CREATEVIEW_NAME) == 0) /* * createView: create a view * * createView NAME SUBTREE MASK * */ { if (++arg + 2 > argc) { fprintf (stderr, "You must specify name, subtree and mask\n"); usage (); exit (1); } command = CMD_CREATEVIEW; name_length = VIEW_OID_LEN; view_oid (vacmViewTreeFamilyStatus, &name_length, argv[arg], argv[arg + 1]); longvar = RS_CREATEANDGO; snmp_pdu_add_variable (pdu, vacmViewTreeFamilyStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof (longvar)); /* * Mask */ if (arg + 3 == argc) { mask = argv[arg + 2]; for (mask = strtok_r (mask, ".:", &st); mask; mask = strtok_r (NULL, ".:", &st)) { if (i >= sizeof (viewMask)) { printf ("MASK too long\n"); exit (1); } if (sscanf (mask, "%x", &val) == 0) { printf ("invalid MASK\n"); exit (1); } viewMask[i] = val; i++; } } else { for (i = 0; i < (name_length + 7) / 8; i++) viewMask[i] = (u_char) 0xff; } view_oid (vacmViewTreeFamilyMask, &name_length, argv[arg], argv[arg + 1]); snmp_pdu_add_variable (pdu, vacmViewTreeFamilyMask, name_length, ASN_OCTET_STR, viewMask, i); view_oid (vacmViewTreeFamilyType, &name_length, argv[arg], argv[arg + 1]); snmp_pdu_add_variable (pdu, vacmViewTreeFamilyType, name_length, ASN_INTEGER, (u_char *) & viewTreeFamilyType, sizeof (viewTreeFamilyType)); } else if (strcmp (argv[arg], CMD_DELETESEC2GROUP_NAME) == 0) /* * deleteSec2Group: delete security2group * * deleteSec2Group MODEL SECURITYNAME * */ { if (++arg + 2 != argc) { fprintf (stderr, "You must specify the sec2group to delete\n"); usage (); exit (1); } command = CMD_DELETESEC2GROUP; name_length = SEC2GROUP_OID_LEN; if (sscanf (argv[arg], "%d", &secModel) == 0) { printf ("invalid security model\n"); usage (); exit (1); } sec2group_oid (vacmSec2GroupStatus, &name_length, secModel, argv[arg + 1]); longvar = RS_DESTROY; snmp_pdu_add_variable (pdu, vacmSec2GroupStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof (longvar)); } else if (strcmp (argv[arg], CMD_CREATESEC2GROUP_NAME) == 0) /* * createSec2Group: create a security2group * * createSec2Group MODEL SECURITYNAME GROUPNAME * */ { if (++arg + 3 != argc) { fprintf (stderr, "You must specify model, security name and group name\n"); usage (); exit (1); } command = CMD_CREATESEC2GROUP; name_length = SEC2GROUP_OID_LEN; if (sscanf (argv[arg], "%d", &secModel) == 0) { printf ("invalid security model\n"); usage (); exit (1); } sec2group_oid (vacmSec2GroupStatus, &name_length, secModel, argv[arg + 1]); longvar = RS_CREATEANDGO; snmp_pdu_add_variable (pdu, vacmSec2GroupStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof (longvar)); sec2group_oid (vacmGroupName, &name_length, secModel, argv[arg + 1]); snmp_pdu_add_variable (pdu, vacmGroupName, name_length, ASN_OCTET_STR, (u_char *) argv[arg + 2], strlen (argv[arg + 2])); } else if (strcmp (argv[arg], CMD_DELETEACCESS_NAME) == 0) /* * deleteAccess: delete access entry * * deleteAccess GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL * */ { if (++arg + 3 > argc) { fprintf (stderr, "You must specify the access entry to delete\n"); usage (); exit (1); } command = CMD_DELETEACCESS; name_length = ACCESS_OID_LEN; groupName = argv[arg]; if (arg + 4 == argc) prefix = argv[++arg]; else prefix = NULL; if (sscanf (argv[arg + 1], "%d", &secModel) == 0) { printf ("invalid security model\n"); usage (); exit (1); } if (sscanf (argv[arg + 2], "%d", &secLevel) == 0) { printf ("invalid security level\n"); usage (); exit (1); } access_oid (vacmAccessStatus, &name_length, groupName, prefix, secModel, secLevel); longvar = RS_DESTROY; snmp_pdu_add_variable (pdu, vacmAccessStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof (longvar)); } else if (strcmp (argv[arg], CMD_CREATEACCESS_NAME) == 0) /* * createAccess: create access entry * * createAccess GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL CONTEXTMATCH READVIEWNAME WRITEVIEWNAME NOTIFYVIEWNAME * */ { if (++arg + 7 > argc) { fprintf (stderr, "You must specify the access entry to create\n"); usage (); exit (1); } command = CMD_CREATEACCESS; name_length = ACCESS_OID_LEN; groupName = argv[arg]; if (arg + 8 == argc) prefix = argv[++arg]; else prefix = NULL; if (sscanf (argv[arg + 1], "%d", &secModel) == 0) { printf ("invalid security model\n"); usage (); exit (1); } if (sscanf (argv[arg + 2], "%d", &secLevel) == 0) { printf ("invalid security level\n"); usage (); exit (1); } access_oid (vacmAccessStatus, &name_length, groupName, prefix, secModel, secLevel); longvar = RS_CREATEANDGO; snmp_pdu_add_variable (pdu, vacmAccessStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof (longvar)); access_oid (vacmAccessContextMatch, &name_length, groupName, prefix, secModel, secLevel); if (sscanf (argv[arg + 3], "%d", &contextMatch) == 0) { printf ("invalid contextMatch\n"); usage (); exit (1); } snmp_pdu_add_variable (pdu, vacmAccessContextMatch, name_length, ASN_INTEGER, (u_char *) & contextMatch, sizeof (contextMatch)); access_oid (vacmAccessReadViewName, &name_length, groupName, prefix, secModel, secLevel); snmp_pdu_add_variable (pdu, vacmAccessReadViewName, name_length, ASN_OCTET_STR, (u_char *) argv[arg + 4], strlen (argv[arg + 4])); access_oid (vacmAccessWriteViewName, &name_length, groupName, prefix, secModel, secLevel); snmp_pdu_add_variable (pdu, vacmAccessWriteViewName, name_length, ASN_OCTET_STR, (u_char *) argv[arg + 5], strlen (argv[arg + 5])); access_oid (vacmAccessNotifyViewName, &name_length, groupName, prefix, secModel, secLevel); snmp_pdu_add_variable (pdu, vacmAccessNotifyViewName, name_length, ASN_OCTET_STR, (u_char *) argv[arg + 6], strlen (argv[arg + 6])); } else if (strcmp (argv[arg], CMD_DELETEAUTH_NAME) == 0) /* * deleteAuth: delete authAccess entry * * deleteAuth GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL AUTHTYPE * */ { if (++arg + 4 > argc) { fprintf (stderr, "You must specify the authAccess entry to delete\n"); usage (); exit (1); } command = CMD_DELETEAUTH; name_length = AUTH_OID_LEN; groupName = argv[arg]; if (arg + 5 == argc) prefix = argv[++arg]; else prefix = NULL; if (sscanf (argv[arg + 1], "%d", &secModel) == 0) { printf ("invalid security model\n"); usage (); exit (1); } if (sscanf (argv[arg + 2], "%d", &secLevel) == 0) { printf ("invalid security level\n"); usage (); exit (1); } authtype = argv[arg + 3]; auth_oid (nsVacmRowStatus, &name_length, groupName, prefix, secModel, secLevel, authtype); longvar = RS_DESTROY; snmp_pdu_add_variable (pdu, nsVacmRowStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof (longvar)); } else if (strcmp (argv[arg], CMD_CREATEAUTH_NAME) == 0) /* * createAuth: create authAccess entry * * createAuth GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL AUTHTYPE CONTEXTMATCH VIEWNAME * */ { if (++arg + 6 > argc) { fprintf (stderr, "You must specify the authAccess entry to create\n"); usage (); exit (1); } command = CMD_CREATEAUTH; name_length = AUTH_OID_LEN; groupName = argv[arg]; if (arg + 7 == argc) prefix = argv[++arg]; else prefix = NULL; if (sscanf (argv[arg + 1], "%d", &secModel) == 0) { printf ("invalid security model\n"); usage (); exit (1); } if (sscanf (argv[arg + 2], "%d", &secLevel) == 0) { printf ("invalid security level\n"); usage (); exit (1); } authtype = argv[arg + 3]; auth_oid (nsVacmRowStatus, &name_length, groupName, prefix, secModel, secLevel, authtype); longvar = RS_CREATEANDGO; snmp_pdu_add_variable (pdu, nsVacmRowStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof (longvar)); auth_oid (nsVacmContextPfx, &name_length, groupName, prefix, secModel, secLevel, authtype); if (sscanf (argv[arg + 4], "%d", &contextMatch) == 0) { printf ("invalid contextMatch\n"); usage (); exit (1); } snmp_pdu_add_variable (pdu, nsVacmContextPfx, name_length, ASN_INTEGER, (u_char *) & contextMatch, sizeof (contextMatch)); auth_oid (nsVacmViewName, &name_length, groupName, prefix, secModel, secLevel, authtype); snmp_pdu_add_variable (pdu, nsVacmViewName, name_length, ASN_OCTET_STR, (u_char *) argv[arg + 5], strlen (argv[arg + 5])); } else { printf ("Unknown command\n"); usage (); exit (1); } /* * do the request */ status = snmp_synch_response (ss, pdu, &response); if (status == STAT_SUCCESS) { if (response) { if (response->errstat == SNMP_ERR_NOERROR) { fprintf (stderr, "%s\n", successNotes[command - 1]); } else { fprintf (stderr, "Error in packet.\nReason: %s\n", snmp_errstring (response->errstat)); if (response->errindex != 0) { int count; struct variable_list *vars = response->variables; fprintf (stderr, "Failed object: "); for (count = 1; vars && (count != response->errindex); vars = vars->next_variable, count++) ; if (vars) fprint_objid (stderr, vars->name, vars->name_length); fprintf (stderr, "\n"); } exitval = 2; } } } else if (status == STAT_TIMEOUT) { fprintf (stderr, "Timeout: No Response from %s\n", session.peername); exitval = 1; } else { snmp_sess_perror ("snmpset", ss); exitval = 1; } if (response) snmp_free_pdu (response); snmp_close (ss); SOCK_CLEANUP; return exitval; }
int main(int argc, char *argv[]) { netsnmp_session session, *ss; netsnmp_pdu *pdu = NULL, *response = NULL; #ifdef notused netsnmp_variable_list *vars; #endif int arg; #ifdef notused int count; int current_name = 0; int current_type = 0; int current_value = 0; char *names[128]; char types[128]; char *values[128]; oid name[MAX_OID_LEN]; #endif size_t name_length = USM_OID_LEN; size_t name_length2 = USM_OID_LEN; int status; int exitval = 0; int rval; int command = 0; long longvar; size_t oldKu_len = SNMP_MAXBUF_SMALL, newKu_len = SNMP_MAXBUF_SMALL, oldkul_len = SNMP_MAXBUF_SMALL, newkul_len = SNMP_MAXBUF_SMALL, keychange_len = SNMP_MAXBUF_SMALL; char *newpass = NULL, *oldpass = NULL; u_char oldKu[SNMP_MAXBUF_SMALL], newKu[SNMP_MAXBUF_SMALL], oldkul[SNMP_MAXBUF_SMALL], newkul[SNMP_MAXBUF_SMALL], keychange[SNMP_MAXBUF_SMALL]; authKeyChange = authKeyOid; privKeyChange = privKeyOid; /* * get the common command line arguments */ switch (arg = snmp_parse_args(argc, argv, &session, "C:", optProc)) { case -2: exit(0); case -1: usage(); exit(1); default: break; } SOCK_STARTUP; /* * open an SNMP session */ /* * Note: this wil obtain the engineID needed below */ ss = snmp_open(&session); if (ss == NULL) { /* * diagnose snmp_open errors with the input netsnmp_session pointer */ snmp_sess_perror("snmpusm", &session); exit(1); } /* * create PDU for SET request and add object names and values to request */ pdu = snmp_pdu_create(SNMP_MSG_SET); if (arg >= argc) { fprintf(stderr, "Please specify a operation to perform.\n"); usage(); exit(1); } if (strcmp(argv[arg], CMD_PASSWD_NAME) == 0) { /* * passwd: change a users password. * * XXX: Uses the auth type of the calling user, a MD5 user can't * change a SHA user's key. */ command = CMD_PASSWD; oldpass = argv[++arg]; newpass = argv[++arg]; if (doprivkey == 0 && doauthkey == 0) doprivkey = doauthkey = 1; if (newpass == NULL || strlen(newpass) < USM_LENGTH_P_MIN) { fprintf(stderr, "New passphrase must be greater than %d characters in length.\n", USM_LENGTH_P_MIN); exit(1); } if (oldpass == NULL || strlen(oldpass) < USM_LENGTH_P_MIN) { fprintf(stderr, "Old passphrase must be greater than %d characters in length.\n", USM_LENGTH_P_MIN); exit(1); } /* * do we have a securityName? If not, copy the default */ if (session.securityName == NULL) { session.securityName = strdup(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_SECNAME)); } /* * the old Ku is in the session, but we need the new one */ if (session.securityAuthProto == NULL) { /* * get .conf set default */ const oid *def = get_default_authtype(&session.securityAuthProtoLen); session.securityAuthProto = snmp_duplicate_objid(def, session.securityAuthProtoLen); } if (session.securityAuthProto == NULL) { /* * assume MD5 */ session.securityAuthProtoLen = sizeof(usmHMACMD5AuthProtocol) / sizeof(oid); session.securityAuthProto = snmp_duplicate_objid(usmHMACMD5AuthProtocol, session.securityAuthProtoLen); } rval = generate_Ku(session.securityAuthProto, session.securityAuthProtoLen, (u_char *) newpass, strlen(newpass), newKu, &newKu_len); if (rval != SNMPERR_SUCCESS) { snmp_perror(argv[0]); fprintf(stderr, "generating the old Ku failed\n"); exit(1); } /* * the old Ku is in the session, but we need the new one */ rval = generate_Ku(session.securityAuthProto, session.securityAuthProtoLen, (u_char *) oldpass, strlen(oldpass), oldKu, &oldKu_len); if (rval != SNMPERR_SUCCESS) { snmp_perror(argv[0]); fprintf(stderr, "generating the new Ku failed\n"); exit(1); } /* * generate the two Kul's */ rval = generate_kul(session.securityAuthProto, session.securityAuthProtoLen, ss->contextEngineID, ss->contextEngineIDLen, oldKu, oldKu_len, oldkul, &oldkul_len); if (rval != SNMPERR_SUCCESS) { snmp_perror(argv[0]); fprintf(stderr, "generating the old Kul failed\n"); exit(1); } rval = generate_kul(session.securityAuthProto, session.securityAuthProtoLen, ss->contextEngineID, ss->contextEngineIDLen, newKu, newKu_len, newkul, &newkul_len); if (rval != SNMPERR_SUCCESS) { snmp_perror(argv[0]); fprintf(stderr, "generating the new Kul failed\n"); exit(1); } /* * create the keychange string */ rval = encode_keychange(session.securityAuthProto, session.securityAuthProtoLen, oldkul, oldkul_len, newkul, newkul_len, keychange, &keychange_len); if (rval != SNMPERR_SUCCESS) { snmp_perror(argv[0]); fprintf(stderr, "encoding the keychange failed\n"); usage(); exit(1); } /* * add the keychange string to the outgoing packet */ if (doauthkey) { setup_oid(authKeyChange, &name_length, ss->contextEngineID, ss->contextEngineIDLen, session.securityName); snmp_pdu_add_variable(pdu, authKeyChange, name_length, ASN_OCTET_STR, keychange, keychange_len); } if (doprivkey) { setup_oid(privKeyChange, &name_length, ss->contextEngineID, ss->contextEngineIDLen, session.securityName); snmp_pdu_add_variable(pdu, privKeyChange, name_length, ASN_OCTET_STR, keychange, keychange_len); } } else if (strcmp(argv[arg], CMD_CREATE_NAME) == 0) { /* * create: create a user * * create USER [CLONEFROM] */ if (++arg >= argc) { fprintf(stderr, "You must specify the user name to create\n"); usage(); exit(1); } command = CMD_CREATE; if (++arg < argc) { /* * clone the new user from an existing user * (and make them active immediately) */ setup_oid(usmUserStatus, &name_length, ss->contextEngineID, ss->contextEngineIDLen, argv[arg-1]); longvar = RS_CREATEANDGO; snmp_pdu_add_variable(pdu, usmUserStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof(longvar)); setup_oid(usmUserCloneFrom, &name_length, ss->contextEngineID, ss->contextEngineIDLen, argv[arg - 1]); setup_oid(usmUserSecurityName, &name_length2, ss->contextEngineID, ss->contextEngineIDLen, argv[arg]); snmp_pdu_add_variable(pdu, usmUserCloneFrom, name_length, ASN_OBJECT_ID, (u_char *) usmUserSecurityName, sizeof(oid) * name_length2); } else { /* * create a new (unauthenticated) user from scratch * The Net-SNMP agent won't allow such a user to be made active. */ setup_oid(usmUserStatus, &name_length, ss->contextEngineID, ss->contextEngineIDLen, argv[arg-1]); longvar = RS_CREATEANDWAIT; snmp_pdu_add_variable(pdu, usmUserStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof(longvar)); } } else if (strcmp(argv[arg], CMD_CLONEFROM_NAME) == 0) { /* * create: clone a user from another * * cloneFrom USER FROM */ if (++arg >= argc) { fprintf(stderr, "You must specify the user name to operate on\n"); usage(); exit(1); } command = CMD_CLONEFROM; setup_oid(usmUserStatus, &name_length, ss->contextEngineID, ss->contextEngineIDLen, argv[arg]); longvar = RS_ACTIVE; snmp_pdu_add_variable(pdu, usmUserStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof(longvar)); setup_oid(usmUserCloneFrom, &name_length, ss->contextEngineID, ss->contextEngineIDLen, argv[arg]); if (++arg >= argc) { fprintf(stderr, "You must specify the user name to clone from\n"); usage(); exit(1); } setup_oid(usmUserSecurityName, &name_length2, ss->contextEngineID, ss->contextEngineIDLen, argv[arg]); snmp_pdu_add_variable(pdu, usmUserCloneFrom, name_length, ASN_OBJECT_ID, (u_char *) usmUserSecurityName, sizeof(oid) * name_length2); } else if (strcmp(argv[arg], CMD_DELETE_NAME) == 0) { /* * delete: delete a user * * delete USER */ if (++arg >= argc) { fprintf(stderr, "You must specify the user name to delete\n"); exit(1); } command = CMD_DELETE; setup_oid(usmUserStatus, &name_length, ss->contextEngineID, ss->contextEngineIDLen, argv[arg]); longvar = RS_DESTROY; snmp_pdu_add_variable(pdu, usmUserStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof(longvar)); } else { fprintf(stderr, "Unknown command\n"); usage(); exit(1); } /* * do the request */ status = snmp_synch_response(ss, pdu, &response); if (status == STAT_SUCCESS) { if (response) { if (response->errstat == SNMP_ERR_NOERROR) { fprintf(stderr, "%s\n", successNotes[command - 1]); } else { fprintf(stderr, "Error in packet.\nReason: %s\n", snmp_errstring(response->errstat)); if (response->errindex != 0) { int count; netsnmp_variable_list *vars; fprintf(stderr, "Failed object: "); for (count = 1, vars = response->variables; vars && count != response->errindex; vars = vars->next_variable, count++) /*EMPTY*/; if (vars) fprint_objid(stderr, vars->name, vars->name_length); fprintf(stderr, "\n"); } exitval = 2; } } } else if (status == STAT_TIMEOUT) { fprintf(stderr, "Timeout: No Response from %s\n", session.peername); exitval = 1; } else { /* status == STAT_ERROR */ snmp_sess_perror("snmpset", ss); exitval = 1; } if (response) snmp_free_pdu(response); snmp_close(ss); SOCK_CLEANUP; return exitval; }
/** * snmp_set2: Gets a single value indicated by the objectid * using snmp. * @handle: a handle to the snmp session needed to make an * snmp transaction. * @objid: string containing the OID entry. * @value: the value received from snmp will be put in this union. * * In the case of multiple values being returned, the type in 'value' will be * ASN_NULL (0x05). Nothing else in 'value' will be filled in. * Use snmp_get_all for doing gets that return multiple values. * * Return value: Returns 0 if successful, -1 if there was an error. **/ SaErrorT snmp_set2(struct snmp_session *ss, oid *objid, size_t objid_len, struct snmp_value *value) { struct snmp_pdu *pdu; struct snmp_pdu *response; struct variable_list *vars; void *dataptr = NULL; int status = 0; SaErrorT rtncode = SA_OK; /* Default - All is OK */ /* * Create the PDU for the data for our request. */ pdu = snmp_pdu_create(SNMP_MSG_SET); switch (value->type) { case ASN_INTEGER: case ASN_UNSIGNED: case ASN_COUNTER: dataptr = &value->integer; break; case ASN_OCTET_STR: dataptr = value->string; break; default: rtncode = SA_ERR_HPI_INVALID_PARAMS; dbg("datatype %c not yet supported by snmp_set2()", value->type); break; } if (rtncode == SA_OK) { /* * Set the data to send out */ /* Old code - snmp_add_var(pdu, objid, objid_len, datatype, dataptr); */ //int retcode = snmp_add_var(pdu, objid, objid_len, datatype, dataptr); snmp_pdu_add_variable(pdu, objid, objid_len, value->type, dataptr, value->str_len); /* * Send the Request out. */ status = snmp_synch_response(ss, pdu, &response); /* * Process the response. */ if (status == STAT_SUCCESS) { vars = response->variables; if (response->errstat == SNMP_ERR_NOERROR) { /* display data */ #ifdef DEBUG fprintf(stderr, "*** snmp_set2 ******************************************\n"); if (CHECK_END(response->variables->type)) { fprint_variable(stderr, response->variables->name, response->variables->name_length, response->variables); } else fprintf(stderr, "snmp_set2(): No idea.\n"); fprintf(stderr, "********************************************************\n"); #endif if (!(CHECK_END(response->variables->type)) ) { /* This is one of the exception condition */ rtncode = SA_ERR_HPI_NOT_PRESENT; dbg("snmp exception %d \n",vars->type); } } else { dbg("snmp_set2: Error in packet, Reason: %s", snmp_errstring(response->errstat)); rtncode = errstat2hpi(response->errstat); } } else { snmp_sess_perror("snmpset", ss); rtncode = snmpstat2hpi(status); } /* Clean up: free the response */ if (response) snmp_free_pdu(response); } return rtncode; }
static int SetSnmp(const char *ip, int port, const char *szoid, int type, void *buffer, unsigned int size, int *pml_result, int *result) { struct snmp_session session, *ss=NULL; struct snmp_pdu *pdu=NULL; struct snmp_pdu *response=NULL; oid anOID[MAX_OID_LEN]; size_t anOID_len = MAX_OID_LEN; unsigned int i, len=0; uint32_t val; *result = HPMUD_R_IO_ERROR; *pml_result = PML_EV_ERROR_UNKNOWN_REQUEST; init_snmp("snmpapp"); snmp_sess_init(&session ); /* set up defaults */ session.peername = (char *)ip; session.version = SNMP_VERSION_1; session.community = (unsigned char *)SnmpPort[port]; session.community_len = strlen((const char *)session.community); ss = snmp_open(&session); /* establish the session */ if (ss == NULL) goto bugout; pdu = snmp_pdu_create(SNMP_MSG_SET); read_objid(szoid, anOID, &anOID_len); switch (type) { case PML_DT_ENUMERATION: case PML_DT_SIGNED_INTEGER: /* Convert PML big-endian to SNMP little-endian byte stream. */ for(i=0, val=0; i<size && i<sizeof(val); i++) val = ((val << 8) | ((unsigned char *)buffer)[i]); snmp_pdu_add_variable(pdu, anOID, anOID_len, ASN_INTEGER, (unsigned char *)&val, sizeof(val)); break; case PML_DT_REAL: case PML_DT_STRING: case PML_DT_BINARY: case PML_DT_NULL_VALUE: case PML_DT_COLLECTION: default: snmp_pdu_add_variable(pdu, anOID, anOID_len, ASN_OCTET_STR, buffer, size); break; } /* Send the request and get response. */ if (snmp_synch_response(ss, pdu, &response) != STAT_SUCCESS) goto bugout; if (response->errstat == SNMP_ERR_NOERROR) { len = size; } *pml_result = SnmpErrorToPml(response->errstat); *result = HPMUD_R_OK; bugout: if (response != NULL) snmp_free_pdu(response); if (ss != NULL) snmp_close(ss); return len; }